13#ifndef dealii_trilinos_tpetra_vector_h
14#define dealii_trilinos_tpetra_vector_h
23#ifdef DEAL_II_TRILINOS_WITH_TPETRA
34# include <Teuchos_Comm.hpp>
35# include <Teuchos_OrdinalTraits.hpp>
36# include <Tpetra_Core.hpp>
37# include <Tpetra_Vector.hpp>
38# include <Tpetra_Version.hpp>
49#ifdef DEAL_II_TRILINOS_WITH_TPETRA
55template <
typename Number>
59# ifdef DEAL_II_TRILINOS_WITH_TPETRA_INST_FLOAT
65# ifdef DEAL_II_TRILINOS_WITH_TPETRA_INST_DOUBLE
71# ifdef DEAL_II_WITH_COMPLEX_VALUES
72# ifdef DEAL_II_TRILINOS_WITH_TPETRA_INST_COMPLEX_FLOAT
78# ifdef DEAL_II_TRILINOS_WITH_TPETRA_INST_COMPLEX_DOUBLE
89 template <
typename Number>
90 class ReadWriteVector;
107 namespace TpetraWrappers
146 template <
typename Number,
148 class VectorReference
156 const size_type index);
162 VectorReference(
const VectorReference &) =
default;
175 const VectorReference &
176 operator=(
const VectorReference &r)
const;
182 operator=(
const VectorReference &r);
187 const VectorReference &
188 operator=(
const Number &s)
const;
193 const VectorReference &
194 operator+=(
const Number &s)
const;
199 const VectorReference &
200 operator-=(
const Number &s)
const;
205 const VectorReference &
206 operator*=(
const Number &s)
const;
211 const VectorReference &
212 operator/=(
const Number &s)
const;
218 operator Number()
const;
225 <<
"An error with error number " << arg1
226 <<
" occurred while calling a Trilinos function");
234 ExcAccessToNonLocalElement,
239 <<
"You are trying to access element " << arg1
240 <<
" of a distributed vector, but this element is not stored "
241 <<
"on the current processor. Note: There are " << arg2
242 <<
" elements stored "
243 <<
"on the current processor from within the range [" << arg3 <<
','
244 << arg4 <<
"] but Trilinos vectors need not store contiguous "
245 <<
"ranges on each processor, and not every element in "
246 <<
"this range may in fact be stored locally."
248 <<
"A common source for this kind of problem is that you "
249 <<
"are passing a 'fully distributed' vector into a function "
250 <<
"that needs read access to vector elements that correspond "
251 <<
"to degrees of freedom on ghost cells (or at least to "
252 <<
"'locally active' degrees of freedom that are not also "
253 <<
"'locally owned'). You need to pass a vector that has these "
254 <<
"elements as ghost entries.");
265 const size_type index;
289 template <
typename Number,
typename MemorySpace = ::MemorySpace::Host>
299 using reference = internal::VectorReference<Number, MemorySpace>;
301 const internal::VectorReference<Number, MemorySpace>;
334 const MPI_Comm communicator = MPI_COMM_WORLD);
353 const bool vector_writable =
false);
370 const MPI_Comm communicator = MPI_COMM_WORLD,
371 const bool omit_zeroing_entries =
false);
389 const IndexSet &locally_relevant_or_ghost_entries,
390 const MPI_Comm communicator = MPI_COMM_WORLD,
391 const bool vector_writable =
false);
399 const bool omit_zeroing_entries =
false);
464 template <
typename OtherNumber>
496 const Teuchos::RCP<const Utilities::MPI::CommunicationPatternBase>
497 &communication_pattern);
612 const bool allow_different_maps =
false);
636 add(
const std::vector<size_type> &indices,
637 const std::vector<Number> &values);
644 add(
const std::vector<size_type> &indices,
645 const ::Vector<Number> &values);
655 const Number *values);
682 const Number *values);
691 set(
const std::vector<size_type> &indices,
692 const std::vector<Number> &values);
884 std::pair<size_type, size_type>
984 Teuchos::RCP<const TpetraTypes::VectorType<Number, MemorySpace>>
991 Teuchos::RCP<TpetraTypes::VectorType<Number, MemorySpace>>
999 const unsigned int precision = 3,
1000 const bool scientific =
true,
1001 const bool across =
true)
const;
1044 <<
"You are trying to access element " << arg1
1045 <<
" of a distributed vector, but this element is not stored "
1046 <<
"on the current processor. Note: There are " << arg2
1047 <<
" elements stored "
1048 <<
"on the current processor from within the range [" << arg3 <<
','
1049 << arg4 <<
"] but Trilinos vectors need not store contiguous "
1050 <<
"ranges on each processor, and not every element in "
1051 <<
"this range may in fact be stored locally."
1053 <<
"A common source for this kind of problem is that you "
1054 <<
"are passing a 'fully distributed' vector into a function "
1055 <<
"that needs read access to vector elements that correspond "
1056 <<
"to degrees of freedom on ghost cells (or at least to "
1057 <<
"'locally active' degrees of freedom that are not also "
1058 <<
"'locally owned'). You need to pass a vector that has these "
1059 <<
"elements as ghost entries.");
1067 "To compress a vector, a locally_relevant_dofs "
1068 "index set, and a locally_owned_dofs index set "
1069 "must be provided. These index sets must be "
1070 "provided either when the vector is initialized "
1071 "or when compress is called. See the documentation "
1072 "of compress() for more information.");
1081 <<
"An error with error number " << arg1
1082 <<
" occurred while calling a Trilinos function");
1121 Teuchos::RCP<TpetraTypes::VectorType<Number, MemorySpace>>
vector;
1128 Teuchos::RCP<TpetraTypes::VectorType<Number, MemorySpace>>
1147 std::remove_const_t<
decltype(Kokkos::ALL)>,
1193 Teuchos::RCP<const TpetraWrappers::CommunicationPattern<MemorySpace>>
1197 friend class internal::VectorReference<Number,
MemorySpace>;
1203 template <
typename Number,
typename MemorySpace>
1212 template <
typename Number,
typename MemorySpace>
1221 template <
typename Number,
typename MemorySpace>
1230 template <
typename Number,
typename MemorySpace>
1234 std::swap(compressed, v.compressed);
1235 std::swap(has_ghost, v.has_ghost);
1236 std::swap(last_action, v.last_action);
1237 vector.swap(v.vector);
1238 nonlocal_vector.swap(v.nonlocal_vector);
1239 std::swap(vector_1d_view, v.vector_1d_view);
1240 std::swap(nonlocal_vector_1d_view, v.nonlocal_vector_1d_view);
1241 std::swap(source_stored_elements, v.source_stored_elements);
1242 std::swap(local_entries, v.local_entries);
1243 std::swap(nonlocal_cached_indices, v.nonlocal_cached_indices);
1244 std::swap(nonlocal_cached_values, v.nonlocal_cached_values);
1245 tpetra_comm_pattern.swap(v.tpetra_comm_pattern);
1250 template <
typename Number,
typename MemorySpace>
1253 const bool allow_different_maps)
1261 template <
typename Number,
typename MemorySpace>
1264 const std::vector<Number> &values)
1270 add(indices.size(), indices.data(), values.data());
1275 template <
typename Number,
typename MemorySpace>
1278 const ::Vector<Number> &values)
1285 add(indices.size(), indices.data(), values.begin());
1290 template <
typename Number,
typename MemorySpace>
1294 const Number *values)
1301 nonlocal_vector.is_null() ||
1305 "Cannot mix add and insert operations on a Tpetra vector "
1306 "with non-locally owned entries without calling compress() in between."));
1316# ifndef HAVE_TEUCHOS_THREAD_SAFE
1318 std::scoped_lock lock(mutex);
1321 vector_map = vector->getMap().ptr();
1324 if (!vector_1d_view)
1326 auto vector_2d_view =
1327 vector->template getLocalView<Kokkos::HostSpace>(
1328 Tpetra::Access::ReadWriteStruct{});
1330 vector_1d_view = Kokkos::subview(vector_2d_view, Kokkos::ALL(), 0);
1333 if (!nonlocal_vector_1d_view && !nonlocal_vector.is_null())
1335 auto nonlocal_vector_2d_view =
1336 nonlocal_vector->template getLocalView<Kokkos::HostSpace>(
1337 Tpetra::Access::ReadWriteStruct{});
1339 nonlocal_vector_1d_view =
1340 Kokkos::subview(nonlocal_vector_2d_view, Kokkos::ALL(), 0);
1344 for (
size_type i = 0; i < n_elements; ++i)
1352 vector_map->getLocalElement(row);
1353 local_row != Teuchos::OrdinalTraits<int>::invalid())
1355 (*vector_1d_view)(local_row) += values[i];
1360 if (nonlocal_vector.get() !=
nullptr)
1363 else if (nonlocal_vector.get() ==
nullptr)
1365# ifndef HAVE_TEUCHOS_THREAD_SAFE
1367 std::scoped_lock lock(mutex);
1374 nonlocal_cached_indices.push_back(row);
1375 nonlocal_cached_values.push_back(values[i]);
1380# ifndef HAVE_TEUCHOS_THREAD_SAFE
1382 std::scoped_lock lock(mutex);
1390 nonlocal_vector->getMap()->getLocalElement(row);
1392# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
1393 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1394 ExcAccessToNonLocalElement(
1396 vector->getMap()->getLocalNumElements(),
1397 vector->getMap()->getMinLocalIndex(),
1398 vector->getMap()->getMaxLocalIndex()));
1400 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1401 ExcAccessToNonLocalElement(
1403 vector->getMap()->getNodeNumElements(),
1404 vector->getMap()->getMinLocalIndex(),
1405 vector->getMap()->getMaxLocalIndex()));
1409 (*nonlocal_vector_1d_view)(nonlocal_row) += values[i];
1417 template <
typename Number,
typename MemorySpace>
1420 const std::vector<Number> &values)
1423 set(indices.size(), indices.data(), values.data());
1428 template <
typename Number,
typename MemorySpace>
1432 const Number *values)
1439 nonlocal_vector.is_null() ||
1443 "Cannot mix add and insert operations on a Tpetra vector "
1444 "with non-locally owned entries without calling compress() in between."));
1454# ifndef HAVE_TEUCHOS_THREAD_SAFE
1456 std::scoped_lock lock(mutex);
1459 vector_map = vector->getMap().ptr();
1462 if (!vector_1d_view)
1464 auto vector_2d_view =
1465 vector->template getLocalView<Kokkos::HostSpace>(
1466 Tpetra::Access::ReadWriteStruct{});
1468 vector_1d_view = Kokkos::subview(vector_2d_view, Kokkos::ALL(), 0);
1471 if (!nonlocal_vector_1d_view && !nonlocal_vector.is_null())
1473 auto nonlocal_vector_2d_view =
1474 nonlocal_vector->template getLocalView<Kokkos::HostSpace>(
1475 Tpetra::Access::ReadWriteStruct{});
1477 nonlocal_vector_1d_view =
1478 Kokkos::subview(nonlocal_vector_2d_view, Kokkos::ALL(), 0);
1482 for (
size_type i = 0; i < n_elements; ++i)
1490 vector_map->getLocalElement(row);
1491 local_row != Teuchos::OrdinalTraits<int>::invalid())
1493 (*vector_1d_view)(local_row) = values[i];
1498 if (nonlocal_vector.get() !=
nullptr)
1501 else if (nonlocal_vector.get() ==
nullptr)
1503# ifndef HAVE_TEUCHOS_THREAD_SAFE
1505 std::scoped_lock lock(mutex);
1512 nonlocal_cached_indices.push_back(row);
1513 nonlocal_cached_values.push_back(values[i]);
1518# ifndef HAVE_TEUCHOS_THREAD_SAFE
1520 std::scoped_lock lock(mutex);
1528 nonlocal_vector->getMap()->getLocalElement(row);
1530# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
1531 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1532 ExcAccessToNonLocalElement(
1534 vector->getMap()->getLocalNumElements(),
1535 vector->getMap()->getMinLocalIndex(),
1536 vector->getMap()->getMaxLocalIndex()));
1538 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1539 ExcAccessToNonLocalElement(
1541 vector->getMap()->getNodeNumElements(),
1542 vector->getMap()->getMinLocalIndex(),
1543 vector->getMap()->getMaxLocalIndex()));
1547 (*nonlocal_vector_1d_view)(nonlocal_row) = values[i];
1555 template <
typename Number,
typename MemorySpace>
1556 inline internal::VectorReference<Number, MemorySpace>
1559 return internal::VectorReference(*
this, index);
1562 template <
typename Number,
typename MemorySpace>
1563 inline internal::VectorReference<Number, MemorySpace>
1569 template <
typename Number,
typename MemorySpace>
1581 template <
typename Number,
typename MemorySpace>
1582 inline VectorReference<Number, MemorySpace>::VectorReference(
1584 const size_type index)
1591 template <
typename Number,
typename MemorySpace>
1592 inline const VectorReference<Number, MemorySpace> &
1593 VectorReference<Number, MemorySpace>::operator=(
1594 const VectorReference<Number, MemorySpace> &r)
const
1600 *
this =
static_cast<Number
>(r);
1607 template <
typename Number,
typename MemorySpace>
1608 inline VectorReference<Number, MemorySpace> &
1609 VectorReference<Number, MemorySpace>::operator=(
1610 const VectorReference<Number, MemorySpace> &r)
1613 *
this =
static_cast<Number
>(r);
1620 template <
typename Number,
typename MemorySpace>
1621 inline const VectorReference<Number, MemorySpace> &
1622 VectorReference<Number, MemorySpace>::operator=(
const Number &value)
const
1626 vector.set(1, &index, &value);
1633 template <
typename Number,
typename MemorySpace>
1634 inline const VectorReference<Number, MemorySpace> &
1635 VectorReference<Number, MemorySpace>::operator+=(
1636 const Number &value)
const
1640 vector.add(1, &index, &value);
1647 template <
typename Number,
typename MemorySpace>
1648 inline const VectorReference<Number, MemorySpace> &
1649 VectorReference<Number, MemorySpace>::operator-=(
1650 const Number &value)
const
1655 vector.add(1, &index, &new_value);
1662 template <
typename Number,
typename MemorySpace>
1663 inline const VectorReference<Number, MemorySpace> &
1664 VectorReference<Number, MemorySpace>::operator*=(
1665 const Number &value)
const
1670 vector.set(1, &index, &new_value);
1677 template <
typename Number,
typename MemorySpace>
1678 inline const VectorReference<Number, MemorySpace> &
1679 VectorReference<Number, MemorySpace>::operator/=(
1680 const Number &value)
const
1685 vector.set(1, &index, &new_value);
1703 namespace LinearOperatorImplementation
1712 template <
typename Number,
typename MemorySpace>
1717 template <
typename Matrix>
1720 const Matrix &matrix,
1722 bool omit_zeroing_entries)
1724 v.
reinit(matrix.locally_owned_range_indices(),
1725 matrix.get_mpi_communicator(),
1726 omit_zeroing_entries);
1729 template <
typename Matrix>
1732 const Matrix &matrix,
1734 bool omit_zeroing_entries)
1736 v.
reinit(matrix.locally_owned_domain_indices(),
1737 matrix.get_mpi_communicator(),
1738 omit_zeroing_entries);
1748template <
typename Number,
typename MemorySpace>
1750 LinearAlgebra::TpetraWrappers::Vector<Number, MemorySpace>> : std::false_type
* x_component_mask set(0, true)
* * Point< dim > operator()(const Point< dim > &p) const *
const TpetraTypes::MapType< MemorySpace > & trilinos_partitioner() const
void reinit(const Vector< Number, MemorySpace > &V, const bool omit_zeroing_entries=false)
void equ(const Number a, const Vector< Number, MemorySpace > &V)
Teuchos::RCP< const TpetraWrappers::CommunicationPattern< MemorySpace > > tpetra_comm_pattern
void reinit(const IndexSet &locally_owned_entries, const IndexSet &locally_relevant_or_ghost_entries, const MPI_Comm communicator=MPI_COMM_WORLD, const bool vector_writable=false)
void add(const Number a, const Vector< Number, MemorySpace > &V, const Number b, const Vector< Number, MemorySpace > &W)
bool is_non_negative() const
std::optional< array_view_type > nonlocal_vector_1d_view
Number add_and_dot(const Number a, const Vector< Number, MemorySpace > &V, const Vector< Number, MemorySpace > &W)
TpetraTypes::VectorType< Number, MemorySpace > & trilinos_vector()
void reinit(const IndexSet ¶llel_partitioner, const MPI_Comm communicator=MPI_COMM_WORLD, const bool omit_zeroing_entries=false)
MPI_Comm get_mpi_communicator() const
Teuchos::RCP< TpetraTypes::VectorType< Number, MemorySpace > > vector
std::optional< array_view_type > vector_1d_view
void sadd(const Number s, const Vector< Number, MemorySpace > &V)
typename dual_view_type::t_host host_view_type
Number operator[](const size_type index) const
bool operator==(const Vector< Number, MemorySpace > &v) const
void scale(const Vector< Number, MemorySpace > &scaling_factors)
void add(const std::vector< size_type > &indices, const ::Vector< Number > &values)
void set(const std::vector< size_type > &indices, const std::vector< Number > &values)
Vector(const IndexSet ¶llel_partitioner, const MPI_Comm communicator=MPI_COMM_WORLD)
void set(const size_type n_elements, const size_type *indices, const Number *values)
MPI_Comm mpi_comm() const
Vector(const Teuchos::RCP< TpetraTypes::VectorType< Number, MemorySpace > > V)
internal::VectorReference< Number, MemorySpace > reference
size_type locally_owned_size() const
reference operator()(const size_type index)
void update_ghost_values() const
virtual void extract_subvector_to(const ArrayView< const types::global_dof_index > &indices, const ArrayView< Number > &elements) const override
const internal::VectorReference< Number, MemorySpace > const_reference
void compress(const VectorOperation::values operation)
std::vector< Number > nonlocal_cached_values
bool is_compressed() const
Kokkos::Subview< host_view_type, std::remove_const_t< decltype(Kokkos::ALL)>, unsigned > array_view_type
VectorOperation::values last_action
bool operator!=(const Vector< Number, MemorySpace > &v) const
Number operator()(const size_type index) const
Vector & operator/=(const Number factor)
std::pair< size_type, size_type > local_range() const
::IndexSet source_stored_elements
void sadd(const Number s, const Number a, const Vector< Number, MemorySpace > &V)
reference operator[](const size_type index)
void add(const Number a, const Vector< Number, MemorySpace > &V)
Vector & operator*=(const Number factor)
void add(const Vector< Number, MemorySpace > &V, const bool allow_different_maps=false)
void add(const size_type n_elements, const size_type *indices, const Number *values)
void import_elements(const ReadWriteVector< Number > &V, VectorOperation::values operation, const Teuchos::RCP< const Utilities::MPI::CommunicationPatternBase > &communication_pattern)
real_type l2_norm() const
void add(const std::vector< size_type > &indices, const std::vector< Number > &values)
typename numbers::NumberTraits< Number >::real_type real_type
Vector & operator-=(const Vector< Number, MemorySpace > &V)
Vector & operator=(const ::Vector< OtherNumber > &V)
::IndexSet locally_owned_elements() const
Vector & operator=(const Vector &V)
Vector & operator=(const Number s)
Vector & operator+=(const Vector< Number, MemorySpace > &V)
const TpetraTypes::VectorType< Number, MemorySpace > & trilinos_vector() const
real_type linfty_norm() const
real_type norm_sqr() const
virtual size_type size() const override
void import_elements(const ReadWriteVector< Number > &V, VectorOperation::values operation)
typename TpetraTypes::VectorType< Number, MemorySpace >::dual_view_type dual_view_type
void create_tpetra_comm_pattern(const IndexSet &source_index_set, const MPI_Comm mpi_comm)
real_type l1_norm() const
std::vector< types::global_dof_index > nonlocal_cached_indices
Teuchos::RCP< const TpetraTypes::VectorType< Number, MemorySpace > > trilinos_rcp() const
Number operator*(const Vector< Number, MemorySpace > &V) const
Number mean_value() const
std::size_t memory_consumption() const
void print(std::ostream &out, const unsigned int precision=3, const bool scientific=true, const bool across=true) const
real_type lp_norm(const real_type p) const
bool has_ghost_elements() const
bool in_local_range(const size_type index) const
Vector(const IndexSet &locally_owned_entries, const IndexSet &ghost_entries, const MPI_Comm communicator, const bool vector_writable=false)
Teuchos::RCP< TpetraTypes::VectorType< Number, MemorySpace > > nonlocal_vector
Teuchos::RCP< TpetraTypes::VectorType< Number, MemorySpace > > trilinos_rcp()
virtual void swap(Vector &v) noexcept
static void reinit_range_vector(const Matrix &matrix, LinearAlgebra::TpetraWrappers::Vector< Number, MemorySpace > &v, bool omit_zeroing_entries)
static void reinit_domain_vector(const Matrix &matrix, LinearAlgebra::TpetraWrappers::Vector< Number, MemorySpace > &v, bool omit_zeroing_entries)
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define DeclException0(Exception0)
static ::ExceptionBase & ExcGhostsPresent()
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
static ::ExceptionBase & ExcVectorTypeNotCompatible()
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcAccessToNonLocalElement(size_type arg1, size_type arg2, size_type arg3, size_type arg4)
#define Assert(cond, exc)
static ::ExceptionBase & ExcMissingIndexSet()
#define AssertDimension(dim1, dim2)
#define DeclExceptionMsg(Exception, defaulttext)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcDifferentParallelPartitioning()
static ::ExceptionBase & ExcMessage(std::string arg1)
static ::ExceptionBase & ExcTrilinosError(int arg1)
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
Tpetra::Map< LO, GO, NodeType< MemorySpace > > MapType
void swap(Vector< Number, MemorySpace > &u, Vector< Number, MemorySpace > &v) noexcept
* * * RotationFunction< dim, Number >::RotationFunction Number(dim)
unsigned int global_dof_index