deal.II version GIT relicensing-6809-ge913b9bb34 2026-09-25 17:20:01+00:00
\(\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\}}\)
Loading...
Searching...
No Matches
trilinos_vector.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 2008 - 2026 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_trilinos_vector_h
14#define dealii_trilinos_vector_h
15
16
17#include <deal.II/base/config.h>
18
19#ifndef DEAL_II_TRILINOS_WITH_EPETRA
22
23#endif
24
25#ifdef DEAL_II_TRILINOS_WITH_EPETRA
29
32# include <deal.II/lac/vector.h>
35
37# include <Epetra_ConfigDefs.h>
38# include <Epetra_FEVector.h>
39# include <Epetra_LocalMap.h>
40# include <Epetra_Map.h>
41# include <Epetra_MpiComm.h>
43
44# include <memory>
45# include <utility>
46# include <vector>
47
48#endif
49
51
52#ifdef DEAL_II_TRILINOS_WITH_EPETRA
53// Forward declarations
54# ifndef DOXYGEN
55namespace LinearAlgebra
56{
57 // Forward declaration
58 template <typename Number>
59 class ReadWriteVector;
60} // namespace LinearAlgebra
61# endif
62
73namespace TrilinosWrappers
74{
75 class SparseMatrix;
76
82 {
83 public:
85 };
86
97 namespace internal
98 {
108 class VectorReference
109 {
110 private:
111 using size_type = VectorTraits::size_type;
112
117 VectorReference(MPI::Vector &vector, const size_type index);
118
119 public:
123 VectorReference(const VectorReference &) = default;
124
136 const VectorReference &
137 operator=(const VectorReference &r) const;
138
142 VectorReference &
143 operator=(const VectorReference &r);
144
148 const VectorReference &
149 operator=(const TrilinosScalar &s) const;
150
154 const VectorReference &
155 operator+=(const TrilinosScalar &s) const;
156
160 const VectorReference &
161 operator-=(const TrilinosScalar &s) const;
162
166 const VectorReference &
167 operator*=(const TrilinosScalar &s) const;
168
172 const VectorReference &
173 operator/=(const TrilinosScalar &s) const;
174
179 operator TrilinosScalar() const;
180
185 int,
186 << "An error with error number " << arg1
187 << " occurred while calling a Trilinos function");
188
189 private:
193 MPI::Vector &vector;
194
198 const size_type index;
199
200 // Make the vector class a friend, so that it can create objects of the
201 // present type.
202 friend class ::TrilinosWrappers::MPI::Vector;
203 };
204 } // namespace internal
209# ifndef DEAL_II_WITH_64BIT_INDICES
210 // define a helper function that queries the global ID of local ID of
211 // an Epetra_BlockMap object by calling either the 32- or 64-bit
212 // function necessary.
213 inline int
214 gid(const Epetra_BlockMap &map, int i)
215 {
216 return map.GID(i);
217 }
218# else
219 // define a helper function that queries the global ID of local ID of
220 // an Epetra_BlockMap object by calling either the 32- or 64-bit
221 // function necessary.
222 inline long long int
223 gid(const Epetra_BlockMap &map, int i)
224 {
225 return map.GID64(i);
226 }
227# endif
228
234 namespace MPI
235 {
236 class BlockVector;
237
412 class Vector : public ReadVector<TrilinosScalar>
413 {
414 public:
424 using const_iterator = const value_type *;
427
437 Vector();
438
442 Vector(const Vector &v);
443
462 explicit Vector(const IndexSet &parallel_partitioning,
463 const MPI_Comm communicator = MPI_COMM_WORLD);
464
476 Vector(const IndexSet &local,
477 const IndexSet &ghost,
478 const MPI_Comm communicator = MPI_COMM_WORLD);
479
494 Vector(const IndexSet &parallel_partitioning,
495 const Vector &v,
496 const MPI_Comm communicator = MPI_COMM_WORLD);
497
510 template <typename Number>
511 Vector(const IndexSet &parallel_partitioning,
512 const ::Vector<Number> &v,
513 const MPI_Comm communicator = MPI_COMM_WORLD);
514
523 Vector(Vector &&v); // NOLINT
524
528 ~Vector() override = default;
529
534 void
535 clear();
536
549 void
550 reinit(const Vector &v, const bool omit_zeroing_entries = false);
551
573 void
574 reinit(const IndexSet &parallel_partitioning,
575 const MPI_Comm communicator = MPI_COMM_WORLD,
576 const bool omit_zeroing_entries = false);
577
612 void
613 reinit(const IndexSet &locally_owned_entries,
614 const IndexSet &locally_relevant_or_ghost_entries,
615 const MPI_Comm communicator = MPI_COMM_WORLD,
616 const bool vector_writable = false);
617
628 void
629 reinit(
630 const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner,
631 const bool make_ghosted = true,
632 const bool vector_writable = false);
633
637 void
638 reinit(const BlockVector &v, const bool import_data = false);
639
656 void
658
680 Vector &
682
712 Vector &
713 operator=(const Vector &v);
714
719 Vector &
720 operator=(Vector &&v) noexcept;
721
729 template <typename Number>
730 Vector &
731 operator=(const ::Vector<Number> &v);
732
750 void
752 const ::TrilinosWrappers::SparseMatrix &matrix,
753 const Vector &vector);
754
761 void
763 const VectorOperation::values operation);
764
770 bool
771 operator==(const Vector &v) const;
772
778 bool
779 operator!=(const Vector &v) const;
780
785 size() const override;
786
793
816 std::pair<size_type, size_type>
817 local_range() const;
818
826 bool
827 in_local_range(const size_type index) const;
828
844
852 bool
854
861 void
863
869 operator*(const Vector &vec) const;
870
875 norm_sqr() const;
876
881 mean_value() const;
882
887 min() const;
888
893 max() const;
894
899 l1_norm() const;
900
906 l2_norm() const;
907
913 lp_norm(const TrilinosScalar p) const;
914
919 linfty_norm() const;
920
941 add_and_dot(const TrilinosScalar a, const Vector &V, const Vector &W);
942
948 bool
949 all_zero() const;
950
956 bool
957 is_non_negative() const;
974 operator()(const size_type index);
975
984 operator()(const size_type index) const;
985
992 operator[](const size_type index);
993
1000 operator[](const size_type index) const;
1001
1017 void
1018 extract_subvector_to(const std::vector<size_type> &indices,
1019 std::vector<TrilinosScalar> &values) const;
1020
1024 virtual void
1026 const ArrayView<const size_type> &indices,
1027 const ArrayView<TrilinosScalar> &elements) const override;
1028
1056 template <typename ForwardIterator, typename OutputIterator>
1057 void
1058 extract_subvector_to(ForwardIterator indices_begin,
1059 const ForwardIterator indices_end,
1060 OutputIterator values_begin) const;
1061
1070 iterator
1072
1078 begin() const;
1079
1084 iterator
1086
1092 end() const;
1093
1108 void
1109 set(const std::vector<size_type> &indices,
1110 const std::vector<TrilinosScalar> &values);
1111
1116 void
1117 set(const std::vector<size_type> &indices,
1118 const ::Vector<TrilinosScalar> &values);
1119
1125 void
1126 set(const size_type n_elements,
1127 const size_type *indices,
1128 const TrilinosScalar *values);
1129
1134 void
1135 add(const std::vector<size_type> &indices,
1136 const std::vector<TrilinosScalar> &values);
1137
1142 void
1143 add(const std::vector<size_type> &indices,
1144 const ::Vector<TrilinosScalar> &values);
1145
1151 void
1152 add(const size_type n_elements,
1153 const size_type *indices,
1154 const TrilinosScalar *values);
1155
1159 Vector &
1161
1165 Vector &
1167
1171 Vector &
1173
1177 Vector &
1179
1184 void
1186
1199 void
1200 add(const Vector &V, const bool allow_different_maps = false);
1201
1205 void
1206 add(const TrilinosScalar a, const Vector &V);
1207
1211 void
1213 const Vector &V,
1214 const TrilinosScalar b,
1215 const Vector &W);
1216
1221 void
1222 sadd(const TrilinosScalar s, const Vector &V);
1223
1227 void
1228 sadd(const TrilinosScalar s, const TrilinosScalar a, const Vector &V);
1229
1235 void
1236 scale(const Vector &scaling_factors);
1237
1241 void
1242 equ(const TrilinosScalar a, const Vector &V);
1254 const Epetra_MultiVector &
1256
1261 Epetra_FEVector &
1263
1268 const Epetra_BlockMap &
1270
1278 void
1279 print(std::ostream &out,
1280 const unsigned int precision = 3,
1281 const bool scientific = true,
1282 const bool across = true) const;
1283
1297 void
1298 swap(Vector &v) noexcept;
1299
1303 std::size_t
1304 memory_consumption() const;
1305
1309 MPI_Comm
1317
1322 int,
1323 << "An error with error number " << arg1
1324 << " occurred while calling a Trilinos function");
1325
1331 size_type,
1332 size_type,
1333 size_type,
1334 size_type,
1335 << "You are trying to access element " << arg1
1336 << " of a distributed vector, but this element is not stored "
1337 << "on the current processor. Note: There are " << arg2
1338 << " elements stored "
1339 << "on the current processor from within the range [" << arg3 << ','
1340 << arg4 << "] but Trilinos vectors need not store contiguous "
1341 << "ranges on each processor, and not every element in "
1342 << "this range may in fact be stored locally."
1343 << "\n\n"
1344 << "A common source for this kind of problem is that you "
1345 << "are passing a 'fully distributed' vector into a function "
1346 << "that needs read access to vector elements that correspond "
1347 << "to degrees of freedom on ghost cells (or at least to "
1348 << "'locally active' degrees of freedom that are not also "
1349 << "'locally owned'). You need to pass a vector that has these "
1350 << "elements as ghost entries.");
1351
1352 private:
1364 Epetra_CombineMode last_action;
1365
1371
1377
1383 std::unique_ptr<Epetra_FEVector> vector;
1384
1390 std::unique_ptr<Epetra_MultiVector> nonlocal_vector;
1391
1396
1397 // Make the reference class a friend.
1399 };
1400
1401
1402
1403 // ------------------- inline and template functions --------------
1404
1405
1413 inline void
1414 swap(Vector &u, Vector &v) noexcept
1415 {
1416 u.swap(v);
1417 }
1418 } // namespace MPI
1419
1420# ifndef DOXYGEN
1421
1422 namespace internal
1423 {
1424 inline VectorReference::VectorReference(MPI::Vector &vector,
1425 const size_type index)
1426 : vector(vector)
1427 , index(index)
1428 {}
1429
1430
1431 inline const VectorReference &
1432 VectorReference::operator=(const VectorReference &r) const
1433 {
1434 // as explained in the class
1435 // documentation, this is not the copy
1436 // operator. so simply pass on to the
1437 // "correct" assignment operator
1438 *this = static_cast<TrilinosScalar>(r);
1439
1440 return *this;
1441 }
1442
1443
1444
1445 inline VectorReference &
1446 VectorReference::operator=(const VectorReference &r)
1447 {
1448 // as above
1449 *this = static_cast<TrilinosScalar>(r);
1450
1451 return *this;
1452 }
1453
1454
1455 inline const VectorReference &
1456 VectorReference::operator=(const TrilinosScalar &value) const
1457 {
1458 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
1459
1460 vector.set(1, &index, &value);
1461
1462 return *this;
1463 }
1464
1465
1466
1467 inline const VectorReference &
1468 VectorReference::operator+=(const TrilinosScalar &value) const
1469 {
1470 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
1471
1472 vector.add(1, &index, &value);
1473
1474 return *this;
1475 }
1476
1477
1478
1479 inline const VectorReference &
1480 VectorReference::operator-=(const TrilinosScalar &value) const
1481 {
1482 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
1483
1484 const TrilinosScalar new_value = -value;
1485 vector.add(1, &index, &new_value);
1486
1487 return *this;
1488 }
1489
1490
1491
1492 inline const VectorReference &
1493 VectorReference::operator*=(const TrilinosScalar &value) const
1494 {
1495 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
1496
1497 const TrilinosScalar new_value =
1498 static_cast<TrilinosScalar>(*this) * value;
1499 vector.set(1, &index, &new_value);
1500
1501 return *this;
1502 }
1503
1504
1505
1506 inline const VectorReference &
1507 VectorReference::operator/=(const TrilinosScalar &value) const
1508 {
1509 Assert(!vector.has_ghost_elements(), ExcGhostsPresent());
1510
1511 const TrilinosScalar new_value =
1512 static_cast<TrilinosScalar>(*this) / value;
1513 vector.set(1, &index, &new_value);
1514
1515 return *this;
1516 }
1517 } // namespace internal
1518
1519
1520
1521 namespace MPI
1522 {
1523 inline bool
1524 Vector::in_local_range(const size_type index) const
1525 {
1526 std::pair<size_type, size_type> range = local_range();
1527
1528 return ((index >= range.first) && (index < range.second));
1529 }
1530
1531
1532
1533 inline IndexSet
1535 {
1537 ExcMessage(
1538 "The locally owned elements have not been properly initialized!"
1539 " This happens for example if this object has been initialized"
1540 " with exactly one overlapping IndexSet."));
1541 return owned_elements;
1542 }
1543
1544
1545
1546 inline bool
1548 {
1549 return has_ghosts;
1550 }
1551
1552
1553
1554 inline void
1556 {}
1557
1558
1559
1560 inline internal::VectorReference
1561 Vector::operator()(const size_type index)
1562 {
1563 return internal::VectorReference(*this, index);
1564 }
1565
1566
1567
1568 inline internal::VectorReference
1569 Vector::operator[](const size_type index)
1570 {
1571 return operator()(index);
1572 }
1573
1574
1575
1576 inline TrilinosScalar
1577 Vector::operator[](const size_type index) const
1578 {
1579 return operator()(index);
1580 }
1581
1582
1583
1584 inline void
1585 Vector::extract_subvector_to(const std::vector<size_type> &indices,
1586 std::vector<TrilinosScalar> &values) const
1587 {
1588 for (size_type i = 0; i < indices.size(); ++i)
1589 values[i] = operator()(indices[i]);
1590 }
1591
1592
1593
1594 inline void
1596 const ArrayView<const size_type> &indices,
1597 const ArrayView<TrilinosScalar> &elements) const
1598 {
1599 AssertDimension(indices.size(), elements.size());
1600 for (unsigned int i = 0; i < indices.size(); ++i)
1601 {
1602 AssertIndexRange(indices[i], size());
1603 elements[i] = (*this)[indices[i]];
1604 }
1605 }
1606
1607
1608
1609 template <typename ForwardIterator, typename OutputIterator>
1610 inline void
1611 Vector::extract_subvector_to(ForwardIterator indices_begin,
1612 const ForwardIterator indices_end,
1613 OutputIterator values_begin) const
1614 {
1615 while (indices_begin != indices_end)
1616 {
1617 *values_begin = operator()(*indices_begin);
1618 ++indices_begin;
1619 ++values_begin;
1620 }
1621 }
1622
1623
1624
1625 inline Vector::iterator
1627 {
1628 return (*vector)[0];
1629 }
1630
1631
1632
1633 inline Vector::iterator
1634 Vector::end()
1635 {
1636 return (*vector)[0] + locally_owned_size();
1637 }
1638
1639
1640
1642 Vector::begin() const
1643 {
1644 return (*vector)[0];
1645 }
1646
1647
1648
1650 Vector::end() const
1651 {
1652 return (*vector)[0] + locally_owned_size();
1653 }
1654
1655
1656
1657 inline void
1658 Vector::set(const std::vector<size_type> &indices,
1659 const std::vector<TrilinosScalar> &values)
1660 {
1661 // if we have ghost values, do not allow
1662 // writing to this vector at all.
1664
1665 AssertDimension(indices.size(), values.size());
1666
1667 set(indices.size(), indices.data(), values.data());
1668 }
1669
1670
1671
1672 inline void
1673 Vector::set(const std::vector<size_type> &indices,
1674 const ::Vector<TrilinosScalar> &values)
1675 {
1676 // if we have ghost values, do not allow
1677 // writing to this vector at all.
1679
1680 AssertDimension(indices.size(), values.size());
1681
1682 set(indices.size(), indices.data(), values.begin());
1683 }
1684
1685
1686
1687 inline void
1688 Vector::set(const size_type n_elements,
1689 const size_type *indices,
1690 const TrilinosScalar *values)
1691 {
1692 // if we have ghost values, do not allow
1693 // writing to this vector at all.
1695
1696 if (last_action == Add)
1697 {
1698 const int ierr = vector->GlobalAssemble(Add);
1699 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1700 }
1701
1702 if (last_action != Insert)
1703 last_action = Insert;
1704
1705 for (size_type i = 0; i < n_elements; ++i)
1706 {
1707 const TrilinosWrappers::types::int_type row = indices[i];
1708 const TrilinosWrappers::types::int_type local_row =
1709 vector->Map().LID(row);
1710 if (local_row != -1)
1711 (*vector)[0][local_row] = values[i];
1712 else
1713 {
1714 const int ierr = vector->ReplaceGlobalValues(1, &row, &values[i]);
1715 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1716 compressed = false;
1717 }
1718 // in set operation, do not use the pre-allocated vector for nonlocal
1719 // entries even if it exists. This is to ensure that we really only
1720 // set the elements touched by the set() method and not all contained
1721 // in the nonlocal entries vector (there is no way to distinguish them
1722 // on the receiving processor)
1723 }
1724 }
1725
1726
1727
1728 inline void
1729 Vector::add(const std::vector<size_type> &indices,
1730 const std::vector<TrilinosScalar> &values)
1731 {
1732 // if we have ghost values, do not allow
1733 // writing to this vector at all.
1735 AssertDimension(indices.size(), values.size());
1736
1737 add(indices.size(), indices.data(), values.data());
1738 }
1739
1740
1741
1742 inline void
1743 Vector::add(const std::vector<size_type> &indices,
1744 const ::Vector<TrilinosScalar> &values)
1745 {
1746 // if we have ghost values, do not allow
1747 // writing to this vector at all.
1749 AssertDimension(indices.size(), values.size());
1750
1751 add(indices.size(), indices.data(), values.begin());
1752 }
1753
1754
1755
1756 inline void
1757 Vector::add(const size_type n_elements,
1758 const size_type *indices,
1759 const TrilinosScalar *values)
1760 {
1761 // if we have ghost values, do not allow
1762 // writing to this vector at all.
1764
1765 if (last_action != Add)
1766 {
1767 if (last_action == Insert)
1768 {
1769 const int ierr = vector->GlobalAssemble(Insert);
1770 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1771 }
1772 last_action = Add;
1773 }
1774
1775 for (size_type i = 0; i < n_elements; ++i)
1776 {
1777 const size_type row = indices[i];
1778 const TrilinosWrappers::types::int_type local_row = vector->Map().LID(
1779 static_cast<TrilinosWrappers::types::int_type>(row));
1780 if (local_row != -1)
1781 (*vector)[0][local_row] += values[i];
1782 else if (nonlocal_vector.get() == nullptr)
1783 {
1784 const int ierr = vector->SumIntoGlobalValues(
1785 1,
1786 reinterpret_cast<const TrilinosWrappers::types::int_type *>(
1787 &row),
1788 &values[i]);
1789 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1790 compressed = false;
1791 }
1792 else
1793 {
1794 // use pre-allocated vector for non-local entries if it exists for
1795 // addition operation
1797 nonlocal_vector->Map().LID(
1798 static_cast<TrilinosWrappers::types::int_type>(row));
1799 Assert(my_row != -1,
1800 ExcMessage(
1801 "Attempted to write into off-processor vector entry "
1802 "that has not be specified as being writable upon "
1803 "initialization"));
1804 (*nonlocal_vector)[0][my_row] += values[i];
1805 compressed = false;
1806 }
1807 }
1808 }
1809
1810
1811
1812 inline Vector::size_type
1813 Vector::size() const
1814 {
1815# ifndef DEAL_II_WITH_64BIT_INDICES
1816 return vector->Map().MaxAllGID() + 1 - vector->Map().MinAllGID();
1817# else
1818 return vector->Map().MaxAllGID64() + 1 - vector->Map().MinAllGID64();
1819# endif
1820 }
1821
1822
1823
1824 inline Vector::size_type
1826 {
1827 return owned_elements.n_elements();
1828 }
1829
1830
1831
1832 inline std::pair<Vector::size_type, Vector::size_type>
1833 Vector::local_range() const
1834 {
1835# ifndef DEAL_II_WITH_64BIT_INDICES
1836 const TrilinosWrappers::types::int_type begin = vector->Map().MinMyGID();
1838 vector->Map().MaxMyGID() + 1;
1839# else
1841 vector->Map().MinMyGID64();
1843 vector->Map().MaxMyGID64() + 1;
1844# endif
1845
1846 Assert(
1847 end - begin == vector->Map().NumMyElements(),
1848 ExcMessage(
1849 "This function only makes sense if the elements that this "
1850 "vector stores on the current processor form a contiguous range. "
1851 "This does not appear to be the case for the current vector."));
1852
1853 return std::make_pair(begin, end);
1854 }
1855
1856
1857
1858 inline TrilinosScalar
1859 Vector::operator*(const Vector &vec) const
1860 {
1861 Assert(vector->Map().SameAs(vec.vector->Map()),
1864
1865 TrilinosScalar result;
1866
1867 const int ierr = vector->Dot(*(vec.vector), &result);
1868 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1869
1870 return result;
1871 }
1872
1873
1874
1875 inline Vector::real_type
1876 Vector::norm_sqr() const
1877 {
1878 const TrilinosScalar d = l2_norm();
1879 return d * d;
1880 }
1881
1882
1883
1884 inline TrilinosScalar
1885 Vector::mean_value() const
1886 {
1888
1890 const int ierr = vector->MeanValue(&mean);
1891 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1892
1893 return mean;
1894 }
1895
1896
1897
1898 inline TrilinosScalar
1899 Vector::min() const
1900 {
1901 TrilinosScalar min_value;
1902 const int ierr = vector->MinValue(&min_value);
1903 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1904
1905 return min_value;
1906 }
1907
1908
1909
1910 inline TrilinosScalar
1911 Vector::max() const
1912 {
1913 TrilinosScalar max_value;
1914 const int ierr = vector->MaxValue(&max_value);
1915 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1916
1917 return max_value;
1918 }
1919
1920
1921
1922 inline Vector::real_type
1923 Vector::l1_norm() const
1924 {
1926
1928 const int ierr = vector->Norm1(&d);
1929 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1930
1931 return d;
1932 }
1933
1934
1935
1936 inline Vector::real_type
1937 Vector::l2_norm() const
1938 {
1940
1942 const int ierr = vector->Norm2(&d);
1943 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1944
1945 return d;
1946 }
1947
1948
1949
1950 inline Vector::real_type
1951 Vector::lp_norm(const TrilinosScalar p) const
1952 {
1954
1955 TrilinosScalar norm = 0;
1956 TrilinosScalar sum = 0;
1957 const size_type n_local = locally_owned_size();
1958
1959 // loop over all the elements because
1960 // Trilinos does not support lp norms
1961 for (size_type i = 0; i < n_local; ++i)
1962 sum += std::pow(std::fabs((*vector)[0][i]), p);
1963
1964 norm = std::pow(sum, static_cast<TrilinosScalar>(1. / p));
1965
1966 return norm;
1967 }
1968
1969
1970
1971 inline Vector::real_type
1972 Vector::linfty_norm() const
1973 {
1974 // while we disallow the other
1975 // norm operations on ghosted
1976 // vectors, this particular norm
1977 // is safe to run even in the
1978 // presence of ghost elements
1980 const int ierr = vector->NormInf(&d);
1981 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1982
1983 return d;
1984 }
1985
1986
1987
1988 inline TrilinosScalar
1990 const Vector &V,
1991 const Vector &W)
1992 {
1993 // if we have ghost values, do not allow
1994 // writing to this vector at all.
1996
1997 this->add(a, V);
1998 return *this * W;
1999 }
2000
2001
2002
2003 // inline also scalar products, vector
2004 // additions etc. since they are all
2005 // representable by a single Trilinos
2006 // call. This reduces the overhead of the
2007 // wrapper class.
2008 inline Vector &
2010 {
2011 // if we have ghost values, do not allow
2012 // writing to this vector at all.
2014 AssertIsFinite(a);
2015
2016 const int ierr = vector->Scale(a);
2017 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2018
2019 return *this;
2020 }
2021
2022
2023
2024 inline Vector &
2026 {
2027 // if we have ghost values, do not allow
2028 // writing to this vector at all.
2030 AssertIsFinite(a);
2031
2032 const TrilinosScalar factor = 1. / a;
2033
2034 AssertIsFinite(factor);
2035
2036 const int ierr = vector->Scale(factor);
2037 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2038
2039 return *this;
2040 }
2041
2042
2043
2044 inline Vector &
2045 Vector::operator+=(const Vector &v)
2046 {
2047 // if we have ghost values, do not allow
2048 // writing to this vector at all.
2050 AssertDimension(size(), v.size());
2051 Assert(vector->Map().SameAs(v.vector->Map()),
2053
2054 const int ierr = vector->Update(1.0, *(v.vector), 1.0);
2055 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2056
2057 return *this;
2058 }
2059
2060
2061
2062 inline Vector &
2063 Vector::operator-=(const Vector &v)
2064 {
2065 // if we have ghost values, do not allow
2066 // writing to this vector at all.
2068 AssertDimension(size(), v.size());
2069 Assert(vector->Map().SameAs(v.vector->Map()),
2071
2072 const int ierr = vector->Update(-1.0, *(v.vector), 1.0);
2073 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2074
2075 return *this;
2076 }
2077
2078
2079
2080 inline void
2082 {
2083 // if we have ghost values, do not allow
2084 // writing to this vector at all.
2086 AssertIsFinite(s);
2087
2088 size_type n_local = locally_owned_size();
2089 for (size_type i = 0; i < n_local; ++i)
2090 (*vector)[0][i] += s;
2091 }
2092
2093
2094
2095 inline void
2096 Vector::add(const TrilinosScalar a, const Vector &v)
2097 {
2098 // if we have ghost values, do not allow
2099 // writing to this vector at all.
2102
2103 AssertIsFinite(a);
2104
2105 const int ierr = vector->Update(a, *(v.vector), 1.);
2106 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2107 }
2108
2109
2110
2111 inline void
2113 const Vector &v,
2114 const TrilinosScalar b,
2115 const Vector &w)
2116 {
2117 // if we have ghost values, do not allow
2118 // writing to this vector at all.
2121 AssertDimension(locally_owned_size(), w.locally_owned_size());
2122
2123 AssertIsFinite(a);
2124 AssertIsFinite(b);
2125
2126 const int ierr = vector->Update(a, *(v.vector), b, *(w.vector), 1.);
2127
2128 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2129 }
2130
2131
2132
2133 inline void
2134 Vector::sadd(const TrilinosScalar s, const Vector &v)
2135 {
2136 // if we have ghost values, do not allow
2137 // writing to this vector at all.
2139 AssertDimension(size(), v.size());
2140
2141 AssertIsFinite(s);
2142
2143 // We assume that the vectors have the same Map
2144 // if the local size is the same and if the vectors are not ghosted
2146 !v.has_ghost_elements())
2147 {
2148 Assert(this->vector->Map().SameAs(v.vector->Map()) == true,
2150 const int ierr = vector->Update(1., *(v.vector), s);
2151 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2152 }
2153 else
2154 {
2155 (*this) *= s;
2156 this->add(v, true);
2157 }
2158 }
2159
2160
2161
2162 inline void
2164 const TrilinosScalar a,
2165 const Vector &v)
2166 {
2167 // if we have ghost values, do not allow
2168 // writing to this vector at all.
2170 AssertDimension(size(), v.size());
2171 AssertIsFinite(s);
2172 AssertIsFinite(a);
2173
2174 // We assume that the vectors have the same Map
2175 // if the local size is the same and if the vectors are not ghosted
2177 !v.has_ghost_elements())
2178 {
2179 Assert(this->vector->Map().SameAs(v.vector->Map()) == true,
2181 const int ierr = vector->Update(a, *(v.vector), s);
2182 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2183 }
2184 else
2185 {
2186 // The two vectors are partitioned differently, or 'v'
2187 // has ghost entries. In that case, we first have to create
2188 // a temporary vector that holds a re-partitioned 'v'
2189 // and to which we can then apply the current operation.
2191 tmp = v;
2192
2193 // Now that we have vectors of the right kind, simply forward
2194 // to the current function again, which should land us in the
2195 // 'if' branch above. (Note that unlike in the function above,
2196 // we cannot easily forward to the add() function without the
2197 // need for a temporary vector because here we also have to
2198 // scale the addition -- it needs to be a*v, not just v, and
2199 // so one way or the other we need a temporary vector. If
2200 // we already need such a temp vector, we might as well forward
2201 // to the current function.)
2202 sadd(s, a, tmp);
2203 }
2204 }
2205
2206
2207
2208 inline void
2209 Vector::scale(const Vector &factors)
2210 {
2211 // if we have ghost values, do not allow
2212 // writing to this vector at all.
2215
2216 const int ierr = vector->Multiply(1.0, *(factors.vector), *vector, 0.0);
2217 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2218 }
2219
2220
2221
2222 inline void
2223 Vector::equ(const TrilinosScalar a, const Vector &v)
2224 {
2225 // if we have ghost values, do not allow
2226 // writing to this vector at all.
2228 AssertIsFinite(a);
2229
2230 // If we don't have the same map, copy.
2231 if (vector->Map().SameAs(v.vector->Map()) == false)
2232 {
2233 this->sadd(0., a, v);
2234 }
2235 else
2236 {
2237 // Otherwise, just update
2238 int ierr = vector->Update(a, *v.vector, 0.0);
2239 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2240
2241 last_action = Zero;
2242 }
2243 }
2244
2245
2246
2247 inline const Epetra_MultiVector &
2249 {
2250 return static_cast<const Epetra_MultiVector &>(*vector);
2251 }
2252
2253
2254
2255 inline Epetra_FEVector &
2257 {
2258 return *vector;
2259 }
2260
2261
2262
2263 inline const Epetra_BlockMap &
2265 {
2266 return vector->Map();
2267 }
2268
2269
2270
2271 inline MPI_Comm
2273 {
2274 const Epetra_MpiComm *mpi_comm =
2275 dynamic_cast<const Epetra_MpiComm *>(&vector->Map().Comm());
2276 return mpi_comm->Comm();
2277 }
2278
2279
2280
2281 template <typename number>
2282 Vector::Vector(const IndexSet &parallel_partitioner,
2283 const ::Vector<number> &v,
2284 const MPI_Comm communicator)
2285 {
2286 *this =
2287 Vector(parallel_partitioner.make_trilinos_map(communicator, true), v);
2288 owned_elements = parallel_partitioner;
2289 }
2290
2291
2292
2293 inline Vector &
2295 {
2296 if (s != TrilinosScalar(0))
2298 AssertIsFinite(s);
2299
2300 // First set the elements of the locally owned part of
2301 // the vector to 's':
2302 const int ierr = vector->PutScalar(s);
2303 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2304
2305 // If the vector has ghost elements, then the assertion
2306 // above checks that s==0. In that case, we're simply
2307 // zeroing out the entire vector and need to also do
2308 // that for the ghost entries of the vector.
2309 if (nonlocal_vector.get() != nullptr)
2310 {
2311 const int ierr = nonlocal_vector->PutScalar(0.);
2312 AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2313 }
2314
2315 return *this;
2316 }
2317 } /* end of namespace MPI */
2318
2319# endif /* DOXYGEN */
2320
2321} /* end of namespace TrilinosWrappers */
2322
2326namespace internal
2327{
2328 namespace LinearOperatorImplementation
2329 {
2330 template <typename>
2331 class ReinitHelper;
2332
2337 template <>
2338 class ReinitHelper<TrilinosWrappers::MPI::Vector>
2339 {
2340 public:
2341 template <typename Matrix>
2342 static void
2343 reinit_range_vector(const Matrix &matrix,
2345 bool omit_zeroing_entries)
2346 {
2347 v.reinit(matrix.locally_owned_range_indices(),
2348 matrix.get_mpi_communicator(),
2349 omit_zeroing_entries);
2350 }
2351
2352 template <typename Matrix>
2353 static void
2354 reinit_domain_vector(const Matrix &matrix,
2356 bool omit_zeroing_entries)
2357 {
2358 v.reinit(matrix.locally_owned_domain_indices(),
2359 matrix.get_mpi_communicator(),
2360 omit_zeroing_entries);
2361 }
2362 };
2363
2364 } // namespace LinearOperatorImplementation
2365} /* namespace internal */
2366
2367
2368
2372template <>
2373struct is_serial_vector<TrilinosWrappers::MPI::Vector> : std::false_type
2374{};
2375
2376#endif
2377
2379
2380#endif
std::size_t size() const
Definition array_view.h:737
size_type size() const
Definition index_set.h:1759
size_type n_elements() const
Definition index_set.h:1917
Epetra_Map make_trilinos_map(const MPI_Comm communicator=MPI_COMM_WORLD, const bool overlapping=false) const
Vector & operator/=(const TrilinosScalar factor)
void compress(VectorOperation::values operation)
Vector(const IndexSet &parallel_partitioning, const ::Vector< Number > &v, const MPI_Comm communicator=MPI_COMM_WORLD)
void sadd(const TrilinosScalar s, const Vector &V)
TrilinosScalar mean_value() const
void add(const size_type n_elements, const size_type *indices, const TrilinosScalar *values)
VectorTraits::size_type size_type
void add(const std::vector< size_type > &indices, const std::vector< TrilinosScalar > &values)
std::unique_ptr< Epetra_MultiVector > nonlocal_vector
void add(const TrilinosScalar s)
void import_elements(const LinearAlgebra::ReadWriteVector< double > &rwv, const VectorOperation::values operation)
MPI_Comm get_mpi_communicator() const
void swap(Vector &v) noexcept
void reinit(const Vector &v, const bool omit_zeroing_entries=false)
const Epetra_BlockMap & trilinos_partitioner() const
reference operator()(const size_type index)
void import_nonlocal_data_for_fe(const ::TrilinosWrappers::SparseMatrix &matrix, const Vector &vector)
std::unique_ptr< Epetra_FEVector > vector
size_type size() const override
bool in_local_range(const size_type index) const
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
friend class internal::VectorReference
real_type lp_norm(const TrilinosScalar p) const
IndexSet locally_owned_elements() const
Vector & operator-=(const Vector &V)
Vector & operator+=(const Vector &V)
const Epetra_MultiVector & trilinos_vector() const
const internal::VectorReference const_reference
std::pair< size_type, size_type > local_range() const
real_type norm_sqr() const
void extract_subvector_to(const std::vector< size_type > &indices, std::vector< TrilinosScalar > &values) const
bool operator!=(const Vector &v) const
~Vector() override=default
virtual void extract_subvector_to(const ArrayView< const size_type > &indices, const ArrayView< TrilinosScalar > &elements) const override
Epetra_FEVector & trilinos_vector()
const_iterator begin() const
real_type linfty_norm() const
internal::VectorReference reference
TrilinosScalar min() const
void set(const std::vector< size_type > &indices, const ::Vector< TrilinosScalar > &values)
void set(const size_type n_elements, const size_type *indices, const TrilinosScalar *values)
void scale(const Vector &scaling_factors)
void equ(const TrilinosScalar a, const Vector &V)
bool operator==(const Vector &v) const
void sadd(const TrilinosScalar s, const TrilinosScalar a, const Vector &V)
reference operator[](const size_type index)
const value_type * const_iterator
void swap(Vector &u, Vector &v) noexcept
size_type locally_owned_size() const
TrilinosScalar operator[](const size_type index) const
TrilinosScalar add_and_dot(const TrilinosScalar a, const Vector &V, const Vector &W)
Vector & operator=(const TrilinosScalar s)
Vector & operator*=(const TrilinosScalar factor)
TrilinosScalar operator*(const Vector &vec) const
void add(const std::vector< size_type > &indices, const ::Vector< TrilinosScalar > &values)
void extract_subvector_to(ForwardIterator indices_begin, const ForwardIterator indices_end, OutputIterator values_begin) const
std::size_t memory_consumption() const
void add(const TrilinosScalar a, const Vector &V, const TrilinosScalar b, const Vector &W)
void add(const TrilinosScalar a, const Vector &V)
void set(const std::vector< size_type > &indices, const std::vector< TrilinosScalar > &values)
TrilinosScalar max() const
Vector & operator=(const ::Vector< Number > &v)
const_iterator end() const
::types::global_dof_index size_type
typename numbers::NumberTraits< Number >::real_type real_type
Definition vector.h:133
bool has_ghost_elements() const
const value_type * const_iterator
Definition vector.h:119
virtual size_type size() const override
value_type * iterator
Definition vector.h:118
size_type locally_owned_size() const
static void reinit_domain_vector(const Matrix &matrix, TrilinosWrappers::MPI::Vector &v, bool omit_zeroing_entries)
static void reinit_range_vector(const Matrix &matrix, TrilinosWrappers::MPI::Vector &v, bool omit_zeroing_entries)
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:38
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition config.h:636
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition config.h:680
#define DeclException0(Exception0)
static ::ExceptionBase & ExcGhostsPresent()
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
static ::ExceptionBase & ExcDifferentParallelPartitioning()
static ::ExceptionBase & ExcAccessToNonLocalElement(size_type arg1, size_type arg2, size_type arg3, size_type arg4)
#define Assert(cond, exc)
#define AssertIsFinite(number)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcTrilinosError(int arg1)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcTrilinosError(int arg1)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
double norm(const FEValuesBase< dim > &fe, const ArrayView< const std::vector< Tensor< 1, dim > > > &Du)
Definition divergence.h:469
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
int gid(const Epetra_BlockMap &map, int i)
T sum(const T &t, const MPI_Comm mpi_communicator)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
unsigned int global_dof_index
Definition types.h:92
double TrilinosScalar
Definition types.h:188