15#ifndef dealii_trilinos_tpetra_vector_h
16#define dealii_trilinos_tpetra_vector_h
25#ifdef DEAL_II_TRILINOS_WITH_TPETRA
36# include <Teuchos_Comm.hpp>
37# include <Teuchos_OrdinalTraits.hpp>
38# include <Tpetra_Core.hpp>
39# include <Tpetra_Vector.hpp>
40# include <Tpetra_Version.hpp>
52template <
typename Number>
56# ifdef HAVE_TPETRA_INST_FLOAT
62# ifdef HAVE_TPETRA_INST_DOUBLE
68# ifdef DEAL_II_WITH_COMPLEX_VALUES
69# ifdef HAVE_TPETRA_INST_COMPLEX_FLOAT
75# ifdef HAVE_TPETRA_INST_COMPLEX_DOUBLE
86 template <
typename Number>
87 class ReadWriteVector;
104 namespace TpetraWrappers
143 template <
typename Number,
145 class VectorReference
153 const size_type index);
159 VectorReference(
const VectorReference &) =
default;
172 const VectorReference &
173 operator=(
const VectorReference &r)
const;
179 operator=(
const VectorReference &r);
184 const VectorReference &
185 operator=(
const Number &s)
const;
190 const VectorReference &
191 operator+=(
const Number &s)
const;
196 const VectorReference &
197 operator-=(
const Number &s)
const;
202 const VectorReference &
203 operator*=(
const Number &s)
const;
208 const VectorReference &
209 operator/=(
const Number &s)
const;
215 operator Number()
const;
222 <<
"An error with error number " << arg1
223 <<
" occurred while calling a Trilinos function");
231 ExcAccessToNonLocalElement,
236 <<
"You are trying to access element " << arg1
237 <<
" of a distributed vector, but this element is not stored "
238 <<
"on the current processor. Note: There are " << arg2
239 <<
" elements stored "
240 <<
"on the current processor from within the range [" << arg3 <<
','
241 << arg4 <<
"] but Trilinos vectors need not store contiguous "
242 <<
"ranges on each processor, and not every element in "
243 <<
"this range may in fact be stored locally."
245 <<
"A common source for this kind of problem is that you "
246 <<
"are passing a 'fully distributed' vector into a function "
247 <<
"that needs read access to vector elements that correspond "
248 <<
"to degrees of freedom on ghost cells (or at least to "
249 <<
"'locally active' degrees of freedom that are not also "
250 <<
"'locally owned'). You need to pass a vector that has these "
251 <<
"elements as ghost entries.");
262 const size_type index;
286 template <
typename Number,
typename MemorySpace = ::MemorySpace::Host>
296 using reference = internal::VectorReference<Number, MemorySpace>;
298 const internal::VectorReference<Number, MemorySpace>;
350 const bool vector_writable =
false);
367 const MPI_Comm communicator = MPI_COMM_WORLD,
368 const bool omit_zeroing_entries =
false);
386 const IndexSet &locally_relevant_or_ghost_entries,
387 const MPI_Comm communicator = MPI_COMM_WORLD,
388 const bool vector_writable =
false);
396 const bool omit_zeroing_entries =
false);
461 template <
typename OtherNumber>
484 const Teuchos::RCP<const Utilities::MPI::CommunicationPatternBase>
485 &communication_pattern);
495 const std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
496 &communication_pattern);
515 std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
516 communication_pattern = {})
632 add(
const std::vector<size_type> &indices,
633 const std::vector<Number> &values);
644 const Number *values);
664 const Number *values);
833 std::pair<size_type, size_type>
917 Teuchos::RCP<const TpetraTypes::VectorType<Number, MemorySpace>>
924 Teuchos::RCP<TpetraTypes::VectorType<Number, MemorySpace>>
932 const unsigned int precision = 3,
933 const bool scientific =
true,
934 const bool across =
true)
const;
977 <<
"You are trying to access element " << arg1
978 <<
" of a distributed vector, but this element is not stored "
979 <<
"on the current processor. Note: There are " << arg2
980 <<
" elements stored "
981 <<
"on the current processor from within the range [" << arg3 <<
','
982 << arg4 <<
"] but Trilinos vectors need not store contiguous "
983 <<
"ranges on each processor, and not every element in "
984 <<
"this range may in fact be stored locally."
986 <<
"A common source for this kind of problem is that you "
987 <<
"are passing a 'fully distributed' vector into a function "
988 <<
"that needs read access to vector elements that correspond "
989 <<
"to degrees of freedom on ghost cells (or at least to "
990 <<
"'locally active' degrees of freedom that are not also "
991 <<
"'locally owned'). You need to pass a vector that has these "
992 <<
"elements as ghost entries.");
1000 "To compress a vector, a locally_relevant_dofs "
1001 "index set, and a locally_owned_dofs index set "
1002 "must be provided. These index sets must be "
1003 "provided either when the vector is initialized "
1004 "or when compress is called. See the documentation "
1005 "of compress() for more information.");
1014 <<
"An error with error number " << arg1
1015 <<
" occurred while calling a Trilinos function");
1046 Teuchos::RCP<TpetraTypes::VectorType<Number, MemorySpace>>
vector;
1053 Teuchos::RCP<TpetraTypes::VectorType<Number, MemorySpace>>
1065 Teuchos::RCP<const TpetraWrappers::CommunicationPattern<MemorySpace>>
1069 friend class internal::VectorReference<Number,
MemorySpace>;
1075 template <
typename Number,
typename MemorySpace>
1084 template <
typename Number,
typename MemorySpace>
1093 template <
typename Number,
typename MemorySpace>
1100 template <
typename Number,
typename MemorySpace>
1104 vector.swap(v.vector);
1108 template <
typename Number,
typename MemorySpace>
1111 const std::vector<Number> &values)
1117 add(indices.size(), indices.data(), values.data());
1122 template <
typename Number,
typename MemorySpace>
1126 const Number *values)
1132# if DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1133 auto vector_2d_local = vector->template getLocalView<Kokkos::HostSpace>(
1134 Tpetra::Access::ReadWrite);
1136 vector->template sync<Kokkos::HostSpace>();
1138 auto vector_2d_local = vector->template getLocalView<Kokkos::HostSpace>();
1147 auto vector_1d_local = Kokkos::subview(vector_2d_local, Kokkos::ALL(), 0);
1148 using ViewType1d =
decltype(vector_1d_local);
1149 std::optional<ViewType1d> vector_1d_nonlocal;
1151# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1154 vector->template modify<Kokkos::HostSpace>();
1157 for (
size_type i = 0; i < n_elements; ++i)
1165 vector->getMap()->getLocalElement(row);
1166 local_row != Teuchos::OrdinalTraits<int>::invalid())
1168 vector_1d_local(local_row) += values[i];
1173 if (nonlocal_vector.get() !=
nullptr)
1183 nonlocal_vector->getMap()->getLocalElement(row);
1185# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
1186 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1187 ExcAccessToNonLocalElement(
1189 vector->getMap()->getLocalNumElements(),
1190 vector->getMap()->getMinLocalIndex(),
1191 vector->getMap()->getMaxLocalIndex()));
1193 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1194 ExcAccessToNonLocalElement(
1196 vector->getMap()->getNodeNumElements(),
1197 vector->getMap()->getMinLocalIndex(),
1198 vector->getMap()->getMaxLocalIndex()));
1206 if (!vector_1d_nonlocal)
1208# if DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1209 auto vector_2d_nonlocal =
1210 nonlocal_vector->template getLocalView<Kokkos::HostSpace>(
1211 Tpetra::Access::ReadWrite);
1213 auto vector_2d_nonlocal =
1214 nonlocal_vector->template getLocalView<Kokkos::HostSpace>();
1217 vector_1d_nonlocal =
1218 Kokkos::subview(vector_2d_nonlocal, Kokkos::ALL(), 0);
1220# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1222 nonlocal_vector->template modify<Kokkos::HostSpace>();
1225 (*vector_1d_nonlocal)(nonlocal_row) += values[i];
1230# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1231 vector->template sync<
1232 typename Tpetra::Vector<Number, int, types::signed_global_dof_index>::
1233 device_type::memory_space>();
1237 if (vector_1d_nonlocal)
1238 nonlocal_vector->template sync<
1239 typename Tpetra::Vector<Number, int, types::signed_global_dof_index>::
1240 device_type::memory_space>();
1246 template <
typename Number,
typename MemorySpace>
1250 const Number *values)
1256# if DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1257 auto vector_2d_local = vector->template getLocalView<Kokkos::HostSpace>(
1258 Tpetra::Access::ReadWrite);
1260 vector->template sync<Kokkos::HostSpace>();
1262 auto vector_2d_local = vector->template getLocalView<Kokkos::HostSpace>();
1271 auto vector_1d_local = Kokkos::subview(vector_2d_local, Kokkos::ALL(), 0);
1272 using ViewType1d =
decltype(vector_1d_local);
1273 std::optional<ViewType1d> vector_1d_nonlocal;
1275# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1278 vector->template modify<Kokkos::HostSpace>();
1281 for (
size_type i = 0; i < n_elements; ++i)
1289 vector->getMap()->getLocalElement(row);
1290 local_row != Teuchos::OrdinalTraits<int>::invalid())
1292 vector_1d_local(local_row) = values[i];
1297 if (nonlocal_vector.get() !=
nullptr)
1307 nonlocal_vector->getMap()->getLocalElement(row);
1309# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0)
1310 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1311 ExcAccessToNonLocalElement(
1313 vector->getMap()->getLocalNumElements(),
1314 vector->getMap()->getMinLocalIndex(),
1315 vector->getMap()->getMaxLocalIndex()));
1317 Assert(nonlocal_row != Teuchos::OrdinalTraits<int>::invalid(),
1318 ExcAccessToNonLocalElement(
1320 vector->getMap()->getNodeNumElements(),
1321 vector->getMap()->getMinLocalIndex(),
1322 vector->getMap()->getMaxLocalIndex()));
1330 if (!vector_1d_nonlocal)
1332# if DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1333 auto vector_2d_nonlocal =
1334 nonlocal_vector->template getLocalView<Kokkos::HostSpace>(
1335 Tpetra::Access::ReadWrite);
1337 auto vector_2d_nonlocal =
1338 nonlocal_vector->template getLocalView<Kokkos::HostSpace>();
1341 vector_1d_nonlocal =
1342 Kokkos::subview(vector_2d_nonlocal, Kokkos::ALL(), 0);
1344# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1346 nonlocal_vector->template modify<Kokkos::HostSpace>();
1349 (*vector_1d_nonlocal)(nonlocal_row) = values[i];
1354# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
1355 vector->template sync<
1356 typename Tpetra::Vector<Number, int, types::signed_global_dof_index>::
1357 device_type::memory_space>();
1361 if (vector_1d_nonlocal)
1362 nonlocal_vector->template sync<
1363 typename Tpetra::Vector<Number, int, types::signed_global_dof_index>::
1364 device_type::memory_space>();
1370 template <
typename Number,
typename MemorySpace>
1371 inline internal::VectorReference<Number, MemorySpace>
1374 return internal::VectorReference(*
this, index);
1377 template <
typename Number,
typename MemorySpace>
1378 inline internal::VectorReference<Number, MemorySpace>
1381 return operator()(index);
1384 template <
typename Number,
typename MemorySpace>
1388 return operator()(index);
1396 template <
typename Number,
typename MemorySpace>
1397 inline VectorReference<Number, MemorySpace>::VectorReference(
1399 const size_type index)
1406 template <
typename Number,
typename MemorySpace>
1407 inline const VectorReference<Number, MemorySpace> &
1408 VectorReference<Number, MemorySpace>::operator=(
1409 const VectorReference<Number, MemorySpace> &r)
const
1415 *
this =
static_cast<Number
>(r);
1422 template <
typename Number,
typename MemorySpace>
1423 inline VectorReference<Number, MemorySpace> &
1424 VectorReference<Number, MemorySpace>::operator=(
1425 const VectorReference<Number, MemorySpace> &r)
1428 *
this =
static_cast<Number
>(r);
1435 template <
typename Number,
typename MemorySpace>
1436 inline const VectorReference<Number, MemorySpace> &
1437 VectorReference<Number, MemorySpace>::operator=(
const Number &value)
const
1439 vector.set(1, &index, &value);
1445 template <
typename Number,
typename MemorySpace>
1446 inline const VectorReference<Number, MemorySpace> &
1447 VectorReference<Number, MemorySpace>::operator+=(
1448 const Number &value)
const
1450 vector.add(1, &index, &value);
1456 template <
typename Number,
typename MemorySpace>
1457 inline const VectorReference<Number, MemorySpace> &
1458 VectorReference<Number, MemorySpace>::operator-=(
1459 const Number &value)
const
1461 Number new_value = -
value;
1462 vector.add(1, &index, &new_value);
1468 template <
typename Number,
typename MemorySpace>
1469 inline const VectorReference<Number, MemorySpace> &
1470 VectorReference<Number, MemorySpace>::operator*=(
1471 const Number &value)
const
1473 Number new_value =
static_cast<Number
>(*this) *
value;
1474 vector.set(1, &index, &new_value);
1480 template <
typename Number,
typename MemorySpace>
1481 inline const VectorReference<Number, MemorySpace> &
1482 VectorReference<Number, MemorySpace>::operator/=(
1483 const Number &value)
const
1485 Number new_value =
static_cast<Number
>(*this) /
value;
1486 vector.set(1, &index, &new_value);
1502 namespace LinearOperatorImplementation
1511 template <
typename Number,
typename MemorySpace>
1516 template <
typename Matrix>
1519 const Matrix &matrix,
1521 bool omit_zeroing_entries)
1523 v.
reinit(matrix.locally_owned_range_indices(),
1524 matrix.get_mpi_communicator(),
1525 omit_zeroing_entries);
1528 template <
typename Matrix>
1531 const Matrix &matrix,
1533 bool omit_zeroing_entries)
1535 v.
reinit(matrix.locally_owned_domain_indices(),
1536 matrix.get_mpi_communicator(),
1537 omit_zeroing_entries);
1547template <
typename Number,
typename MemorySpace>
1549 LinearAlgebra::TpetraWrappers::Vector<Number, MemorySpace>> : std::false_type
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
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
Number operator[](const size_type index) const
bool operator==(const Vector< Number, MemorySpace > &v) const
Vector(const IndexSet ¶llel_partitioner, const MPI_Comm communicator)
void scale(const Vector< Number, MemorySpace > &scaling_factors)
void set(const size_type n_elements, const size_type *indices, const Number *values)
void import_elements(const ReadWriteVector< Number > &V, VectorOperation::values operation, const std::shared_ptr< const Utilities::MPI::CommunicationPatternBase > &communication_pattern)
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)
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)
bool is_compressed() const
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 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)
void create_tpetra_comm_pattern(const IndexSet &source_index_set, const MPI_Comm mpi_comm)
real_type l1_norm() const
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
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_DEPRECATED
#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 & 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)
static ::ExceptionBase & ExcInternalError()
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcDifferentParallelPartitioning()
static ::ExceptionBase & ExcTrilinosError(int arg1)
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
void swap(Vector< Number, MemorySpace > &u, Vector< Number, MemorySpace > &v) noexcept
unsigned int global_dof_index