From: Sebastian Kinnewig Date: Tue, 17 Oct 2023 14:24:40 +0000 (+0200) Subject: Qualify TpetraWrappers::Vectors for use with AffineConstraints. X-Git-Tag: relicensing~356^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F16156%2Fhead;p=dealii.git Qualify TpetraWrappers::Vectors for use with AffineConstraints. --- diff --git a/doc/news/changes/minor/20231018SebastianKinnewig b/doc/news/changes/minor/20231018SebastianKinnewig new file mode 100644 index 0000000000..54bf0e0d88 --- /dev/null +++ b/doc/news/changes/minor/20231018SebastianKinnewig @@ -0,0 +1,6 @@ +New: LinearAlgebra::TpetraWrappers::VectorReference for easier access +to LinearAlgebra::TpetraWrappers::Vector. Moreover, several +new member functions are introduced to LinearAlgebra::TpetraWrappers::Vector +to be used as the "VectorType" template argument in AffineConstraints. +
+(Sebastian Kinnewig, 2023/10/18) diff --git a/include/deal.II/lac/trilinos_tpetra_communication_pattern.h b/include/deal.II/lac/trilinos_tpetra_communication_pattern.h index a759cf9ed5..9a88e53faa 100644 --- a/include/deal.II/lac/trilinos_tpetra_communication_pattern.h +++ b/include/deal.II/lac/trilinos_tpetra_communication_pattern.h @@ -87,28 +87,40 @@ namespace LinearAlgebra const Tpetra::Import & get_tpetra_import() const; + /** + * Return a Teuchos::RCP to the underlying Tpetra::Import object. + */ + Teuchos::RCP> + get_tpetra_import_rcp() const; + /** * Return the underlying Tpetra::Export object. */ const Tpetra::Export & get_tpetra_export() const; + /** + * Return a Teuchos::RCP to the underlying Tpetra::Export object. + */ + Teuchos::RCP> + get_tpetra_export_rcp() const; + private: /** - * Shared pointer to the MPI communicator used. + * Teuchos::RCP to the MPI communicator used. */ - std::shared_ptr comm; + Teuchos::RCP comm; /** - * Shared pointer to the Tpetra::Import object used. + * Teuchos::RCP to the Tpetra::Import object used. */ - std::unique_ptr> + Teuchos::RCP> tpetra_import; /** - * Shared pointer to the Tpetra::Export object used. + * Teuchos::RCP to the Tpetra::Export object used. */ - std::unique_ptr> + Teuchos::RCP> tpetra_export; }; } // end of namespace TpetraWrappers diff --git a/include/deal.II/lac/trilinos_tpetra_vector.h b/include/deal.II/lac/trilinos_tpetra_vector.h index faa6f84026..e53d38d15c 100644 --- a/include/deal.II/lac/trilinos_tpetra_vector.h +++ b/include/deal.II/lac/trilinos_tpetra_vector.h @@ -83,15 +83,150 @@ namespace LinearAlgebra class ReadWriteVector; # endif + /** + * @addtogroup TpetraWrappers + * @{ + */ + /** * A namespace for classes that provide wrappers for Trilinos' Tpetra vectors. * * This namespace provides wrappers for the Tpetra::Vector class from the * Tpetra package (https://trilinos.github.io/tpetra.html) that is part of * Trilinos. + * + * @ingroup TpetraWrappers */ namespace TpetraWrappers { + /** + * @cond internal + */ + + /** + * A namespace for internal implementation details of the TrilinosWrapper + * members. + * + * @ingroup TpetraWrappers + */ + namespace internal + { + /** + * Declare type for container size. + */ + using size_type = dealii::types::global_dof_index; + + /** + * This class implements a wrapper for accessing the Trilinos Tpetra + * vector in the same way as we access deal.II objects: it is initialized + * with a vector and an element within it, and has a conversion operator + * to extract the scalar value of this element. It also has a variety of + * assignment operator for writing to this one element. + * + * @ingroup TpetraWrappers + */ + template + class VectorReference + { + private: + /** + * Constructor. It is made private so as to only allow the actual vector + * class to create it. + */ + VectorReference(Vector &vector, const size_type index); + + public: + /** + * Copy constructor. + */ + VectorReference(const VectorReference &) = default; + + /** + * This looks like a copy operator, but does something different than + * usual. In particular, it does not copy the member variables of this + * reference. Rather, it handles the situation where we have two vectors + * @p v and @p w, and assign elements like in v(i)=w(i). Here, + * both left and right hand side of the assignment have data type + * VectorReference, but what we really mean is to assign the vector + * elements represented by the two references. This operator implements + * this operation. Note also that this allows us to make the assignment + * operator const. + */ + const VectorReference & + operator=(const VectorReference &r) const; + + /** + * Same as above but for non-const reference objects. + */ + VectorReference & + operator=(const VectorReference &r); + + /** + * Set the referenced element of the vector to s. + */ + const VectorReference & + operator=(const Number &s) const; + + /** + * Add s to the referenced element of the vector-> + */ + const VectorReference & + operator+=(const Number &s) const; + + /** + * Subtract s from the referenced element of the vector-> + */ + const VectorReference & + operator-=(const Number &s) const; + + /** + * Multiply the referenced element of the vector by s. + */ + const VectorReference & + operator*=(const Number &s) const; + + /** + * Divide the referenced element of the vector by s. + */ + const VectorReference & + operator/=(const Number &s) const; + + /** + * Convert the reference to an actual value, i.e. return the value of + * the referenced element of the vector. + */ + operator Number() const; + + /** + * Exception + */ + DeclException1(ExcTrilinosError, + int, + << "An error with error number " << arg1 + << " occurred while calling a Trilinos function"); + + private: + /** + * Point to the vector we are referencing. + */ + Vector &vector; + + /** + * Index of the referenced element of the vector. + */ + const size_type index; + + // Make the vector class a friend, so that it can create objects of the + // present type. + friend class Vector; + }; // class VectorReference + + } // namespace internal + /** + * @endcond + */ + + /** * This class implements a wrapper to the Trilinos distributed vector * class Tpetra::Vector. This class requires Trilinos to be @@ -108,19 +243,32 @@ namespace LinearAlgebra * actions on the GPU. In particular, there is no need for manually * synchronizing memory between host and @ref GlossDevice "device". * - * @ingroup TrilinosWrappers + * @ingroup TpetraWrappers * @ingroup Vectors */ template class Vector : public ReadVector, public Subscriptor { public: + /** + * Declare some of the standard types used in all containers. + */ using value_type = Number; using real_type = typename numbers::NumberTraits::real_type; using size_type = types::global_dof_index; + using reference = internal::VectorReference; + using MapType = Tpetra::Map; + using VectorType = + Tpetra::Vector; /** - * Constructor. Create a vector of dimension zero. + * @name 1: Basic Object-handling + */ + /** @{ */ + /** + * Default constructor that generates an empty (zero size) vector. The + * function reinit() will have to give the vector the correct + * size and distribution among processes in case of an MPI run. */ Vector(); @@ -130,6 +278,11 @@ namespace LinearAlgebra */ Vector(const Vector &V); + /** + * Copy constructor from Teuchos::RCP. + */ + Vector(const Teuchos::RCP V); + /** * This constructor takes an IndexSet that defines how to distribute the * individual components among the MPI processors. Since it also @@ -150,6 +303,26 @@ namespace LinearAlgebra const MPI_Comm communicator, const bool omit_zeroing_entries = false); + + /** + * Reinit functionality. This function destroys the old vector content + * and generates a new one based on the input partitioning. In addition + * to just specifying one index set as in all the other methods above, + * this method allows to supply an additional set of ghost entries. + * + * Depending on whether the @p locally_relevant_or_ghost_entries argument uniquely + * subdivides elements among processors or not, the resulting vector may + * or may not have ghost elements. See the general documentation of this + * class for more information. + * + * @see + * @ref GlossGhostedVector "vectors with ghost elements" + */ + void + reinit(const IndexSet &locally_owned_entries, + const IndexSet &locally_relevant_or_ghost_entries, + const MPI_Comm communicator = MPI_COMM_WORLD); + /** * Change the dimension to that of the vector @p V. The elements of @p V are not * copied. @@ -189,11 +362,32 @@ namespace LinearAlgebra * improve performance. */ void + import_elements( + const ReadWriteVector &V, + VectorOperation::values operation, + const Teuchos::RCP + &communication_pattern); + + /** + * @deprecated Use Teuchos::RCP<> instead of std::shared_ptr<>. + */ + DEAL_II_DEPRECATED + void import_elements( const ReadWriteVector &V, VectorOperation::values operation, const std::shared_ptr - &communication_pattern = {}); + &communication_pattern); + + /* + * Imports all the elements present in the vector's IndexSet from the + * input vector @p V. VectorOperation::values @p operation is used to decide if + * the elements in @p V should be added to the current vector or replace the + * current elements. + */ + void + import_elements(const ReadWriteVector &V, + VectorOperation::values operation); /** * @deprecated Use import_elements() instead. @@ -208,6 +402,32 @@ namespace LinearAlgebra import_elements(V, operation, communication_pattern); } + /** @} */ + + + /** + * @name 2: Data-Access + */ + /** @{ */ + + /** + * Provide access to a given element, both read and write. + * + * When using a vector distributed with MPI, this operation only makes + * sense for elements that are actually present on the calling processor. + * Otherwise, an exception is thrown. + */ + reference + operator()(const size_type index); + + /** @} */ + + + /** + * @name 3: Modification of vectors + */ + /** @{ */ + /** * Multiply the entire vector by a fixed factor. */ @@ -262,6 +482,25 @@ namespace LinearAlgebra const Number b, const Vector &W); + /** + * A collective add operation: This function adds a whole set of values + * stored in @p values to the vector components specified by @p indices. + */ + void + add(const std::vector &indices, + const std::vector &values); + + + /** + * Take an address where n_elements are stored contiguously and + * add them into the vector. Handles all cases which are not covered by + * the other two add() functions above. + */ + void + add(const size_type n_elements, + const size_type *indices, + const Number *values); + /** * Scaling and simple addition of a multiple of a vector, i.e. *this * = s*(*this)+a*V. @@ -269,6 +508,17 @@ namespace LinearAlgebra void sadd(const Number s, const Number a, const Vector &V); + /** + * A collective set operation: instead of setting individual elements of a + * vector, this function allows to set a whole set of elements at once. + * It is assumed that the elements to be set are located in contiguous + * memory. + */ + void + set(const size_type n_elements, + const size_type *indices, + const Number *values); + /** * Scale each element of this vector by the corresponding element in the * argument. This function is mostly meant to simulate multiplication @@ -290,6 +540,14 @@ namespace LinearAlgebra bool all_zero() const; + /** @} */ + + + /** + * @name 4: Scalar products, norms and related operations + */ + /** @{ */ + /** * Return the mean value of the element of this vector. */ @@ -343,6 +601,15 @@ namespace LinearAlgebra add_and_dot(const Number a, const Vector &V, const Vector &W); + + /** @} */ + + + /** + * @name 5: Scalar products, norms and related operations + */ + /** @{ */ + /** * This function always returns false and is present only for backward * compatibility. @@ -384,6 +651,13 @@ namespace LinearAlgebra ::dealii::IndexSet locally_owned_elements() const; + /** @} */ + + + /** + * @name 6: Mixed stuff + */ + /** @{ */ /** * Compress the underlying representation of the Trilinos object, i.e. * flush the buffers of the vector object if it has any. This function is @@ -396,6 +670,7 @@ namespace LinearAlgebra */ void compress(const VectorOperation::values operation); + /** * Return a const reference to the underlying Trilinos * Tpetra::Vector class. @@ -410,6 +685,21 @@ namespace LinearAlgebra Tpetra::Vector & trilinos_vector(); + /** + * Return a const Teuchos::RCP to the underlying Trilinos + * Tpetra::Vector class. + */ + Teuchos::RCP< + const Tpetra::Vector> + trilinos_rcp() const; + + /** + * Return a (modifiable) Teuchos::RCP to the underlying Trilinos + * Tpetra::Vector class. + */ + Teuchos::RCP> + trilinos_rcp(); + /** * Prints the vector to the output stream @p out. */ @@ -425,9 +715,20 @@ namespace LinearAlgebra std::size_t memory_consumption() const; + /** + * Return the mpi communicator + */ + const MPI_Comm + mpi_comm() const; + + /** @} */ + + /** * The vectors have different partitioning, i.e. their IndexSet objects * don't represent the same indices. + * + * @ingroup Exceptions */ DeclException0(ExcDifferentParallelPartitioning); @@ -459,11 +760,9 @@ namespace LinearAlgebra const MPI_Comm mpi_comm); /** - * Pointer to the actual Tpetra vector object. + * Teuchos::RCP to the actual Tpetra vector object. */ - std::unique_ptr< - Tpetra::Vector> - vector; + Teuchos::RCP vector; /** * IndexSet of the elements of the last imported vector. @@ -474,20 +773,220 @@ namespace LinearAlgebra * CommunicationPattern for the communication between the * source_stored_elements IndexSet and the current vector. */ - std::shared_ptr + Teuchos::RCP tpetra_comm_pattern; + + // Make the reference class a friend. + friend class internal::VectorReference; }; + /* ------------------------- Inline functions ---------------------- */ + template inline bool Vector::has_ghost_elements() const { return false; } + + + + template + inline void + Vector::add(const std::vector &indices, + const std::vector &values) + { + // if we have ghost values, do not allow + // writing to this vector at all. + AssertDimension(indices.size(), values.size()); + + add(indices.size(), indices.data(), values.data()); + } + + + + template + inline void + Vector::add(const size_type n_elements, + const size_type *indices, + const Number *values) + { +# if DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0) + auto vector_2d = vector->template getLocalView( + Tpetra::Access::ReadWrite); +# else + vector->template sync(); + auto vector_2d = vector.template getLocalView(); +# endif + auto vector_1d = Kokkos::subview(vector_2d, Kokkos::ALL(), 0); +# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0) + vector->template modify(); +# endif + + for (size_type i = 0; i < n_elements; ++i) + { + const size_type row = indices[i]; + const TrilinosWrappers::types::int_type local_row = + vector->getMap()->getLocalElement(row); + + if (local_row != Teuchos::OrdinalTraits::invalid()) + vector_1d(local_row) += values[i]; + } + +# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0) + vector->template sync< + typename Tpetra::Vector:: + device_type::memory_space>(); +# endif + } + + + + template + inline void + Vector::set(const size_type n_elements, + const size_type *indices, + const Number *values) + { +# if DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0) + auto vector_2d = vector->template getLocalView( + Tpetra::Access::ReadWrite); +# else + vector->template sync(); + auto vector_2d = vector->template getLocalView(); +# endif + auto vector_1d = Kokkos::subview(vector_2d, Kokkos::ALL(), 0); +# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0) + vector->template modify(); +# endif + + for (size_type i = 0; i < n_elements; ++i) + { + const size_type row = indices[i]; + const TrilinosWrappers::types::int_type local_row = + vector->getMap()->getLocalElement(row); + + if (local_row != Teuchos::OrdinalTraits::invalid()) + vector_1d(local_row) = values[i]; + } + +# if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0) + vector->template sync< + typename Tpetra::Vector:: + device_type::memory_space>(); +# endif + } + + + + template + inline internal::VectorReference + Vector::operator()(const size_type index) + { + return internal::VectorReference(*this, index); + } + +# ifndef DOXYGEN + + // VectorReference + namespace internal + { + template + inline VectorReference::VectorReference(Vector &vector, + const size_type index) + : vector(vector) + , index(index) + {} + + + + template + inline const VectorReference & + VectorReference::operator=(const VectorReference &r) const + { + // as explained in the class + // documentation, this is not the copy + // operator. so simply pass on to the + // "correct" assignment operator + *this = static_cast(r); + + return *this; + } + + + + template + inline VectorReference & + VectorReference::operator=(const VectorReference &r) + { + // as above + *this = static_cast(r); + + return *this; + } + + + + template + inline const VectorReference & + VectorReference::operator=(const Number &value) const + { + vector.set(1, &index, &value); + return *this; + } + + + + template + inline const VectorReference & + VectorReference::operator+=(const Number &value) const + { + vector.add(1, &index, &value); + return *this; + } + + + + template + inline const VectorReference & + VectorReference::operator-=(const Number &value) const + { + Number new_value = -value; + vector.add(1, &index, &new_value); + return *this; + } + + + + template + inline const VectorReference & + VectorReference::operator*=(const Number &value) const + { + Number new_value = static_cast(*this) * value; + vector.set(1, &index, &new_value); + return *this; + } + + + + template + inline const VectorReference & + VectorReference::operator/=(const Number &value) const + { + Number new_value = static_cast(*this) / value; + vector.set(1, &index, &new_value); + return *this; + } + } // namespace internal + +# endif /* DOXYGEN */ + } // namespace TpetraWrappers -} // namespace LinearAlgebra + /** @} */ + +} // namespace LinearAlgebra /** * Declare dealii::LinearAlgebra::TpetraWrappers::Vector as distributed vector. diff --git a/include/deal.II/lac/trilinos_tpetra_vector.templates.h b/include/deal.II/lac/trilinos_tpetra_vector.templates.h index 1d5c78161b..eccc2f41ee 100644 --- a/include/deal.II/lac/trilinos_tpetra_vector.templates.h +++ b/include/deal.II/lac/trilinos_tpetra_vector.templates.h @@ -47,12 +47,8 @@ namespace LinearAlgebra template Vector::Vector() : Subscriptor() - , vector(new Tpetra::Vector( - Teuchos::RCP>( - new Tpetra::Map( - 0, - 0, - Utilities::Trilinos::tpetra_comm_self())))) + , vector(new VectorType(Teuchos::rcp( + new MapType(0, 0, Utilities::Trilinos::tpetra_comm_self())))) {} @@ -60,9 +56,15 @@ namespace LinearAlgebra template Vector::Vector(const Vector &V) : Subscriptor() - , vector(new Tpetra::Vector( - V.trilinos_vector(), - Teuchos::Copy)) + , vector(new VectorType(V.trilinos_vector(), Teuchos::Copy)) + {} + + + + template + Vector::Vector(const Teuchos::RCP V) + : Subscriptor() + , vector(V) {} @@ -71,7 +73,7 @@ namespace LinearAlgebra Vector::Vector(const IndexSet ¶llel_partitioner, const MPI_Comm communicator) : Subscriptor() - , vector(new Tpetra::Vector( + , vector(new VectorType( parallel_partitioner.make_tpetra_map_rcp(communicator, false))) {} @@ -83,12 +85,11 @@ namespace LinearAlgebra const MPI_Comm communicator, const bool omit_zeroing_entries) { - Teuchos::RCP> input_map = + Teuchos::RCP input_map = parallel_partitioner.make_tpetra_map_rcp(communicator, false); + if (vector->getMap()->isSameAs(*input_map) == false) - vector = std::make_unique< - Tpetra::Vector>( - input_map); + vector = Teuchos::rcp(new VectorType(input_map)); else if (omit_zeroing_entries == false) { vector->putScalar(0.); @@ -97,6 +98,23 @@ namespace LinearAlgebra + template + void + Vector::reinit(const IndexSet &locally_owned_entries, + const IndexSet &ghost_entries, + const MPI_Comm communicator) + { + IndexSet parallel_partitioner = locally_owned_entries; + parallel_partitioner.add_indices(ghost_entries); + + Teuchos::RCP input_map = + parallel_partitioner.make_tpetra_map_rcp(communicator, true); + + vector = Teuchos::rcp(new VectorType(input_map)); + } + + + template void Vector::reinit(const Vector &V, @@ -170,9 +188,7 @@ namespace LinearAlgebra Tpetra::REPLACE); } else - vector = std::make_unique< - Tpetra::Vector>( - V.trilinos_vector()); + vector = Teuchos::rcp(new VectorType(V.trilinos_vector())); } return *this; @@ -199,12 +215,12 @@ namespace LinearAlgebra Vector::import_elements( const ReadWriteVector &V, VectorOperation::values operation, - const std::shared_ptr + const Teuchos::RCP &communication_pattern) { // If no communication pattern is given, create one. Otherwise, use the // one given. - if (communication_pattern == nullptr) + if (communication_pattern.is_null()) { // The first time import is called, a communication pattern is // created. Check if the communication pattern already exists and if @@ -223,19 +239,20 @@ namespace LinearAlgebra } else { - tpetra_comm_pattern = std::dynamic_pointer_cast< + tpetra_comm_pattern = Teuchos::rcp_dynamic_cast< const TpetraWrappers::CommunicationPattern>(communication_pattern); + AssertThrow( - tpetra_comm_pattern != nullptr, + tpetra_comm_pattern.is_null(), ExcMessage( std::string("The communication pattern is not of type ") + "LinearAlgebra::TpetraWrappers::CommunicationPattern.")); } - Tpetra::Export tpetra_export( - tpetra_comm_pattern->get_tpetra_export()); - Tpetra::Vector source_vector( - tpetra_export.getSourceMap()); + Teuchos::RCP> + tpetra_export = tpetra_comm_pattern->get_tpetra_export_rcp(); + + VectorType source_vector(tpetra_export->getSourceMap()); { # if DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0) @@ -260,15 +277,41 @@ namespace LinearAlgebra # endif } if (operation == VectorOperation::insert) - vector->doExport(source_vector, tpetra_export, Tpetra::REPLACE); + vector->doExport(source_vector, *tpetra_export, Tpetra::REPLACE); else if (operation == VectorOperation::add) - vector->doExport(source_vector, tpetra_export, Tpetra::ADD); + vector->doExport(source_vector, *tpetra_export, Tpetra::ADD); else AssertThrow(false, ExcNotImplemented()); } + template + void + Vector::import_elements( + const ReadWriteVector &V, + VectorOperation::values operation, + const std::shared_ptr + &communication_pattern) + { + import_elements(V, operation); + } + + + template + void + Vector::import_elements(const ReadWriteVector &V, + VectorOperation::values operation) + { + // Create an empty CommunicationPattern + const Teuchos::RCP + communication_pattern_empty; + + import_elements(V, operation, communication_pattern_empty); + } + + + template Vector & Vector::operator*=(const Number factor) @@ -624,6 +667,25 @@ namespace LinearAlgebra + template + Teuchos::RCP> + Vector::trilinos_rcp() + { + return vector; + } + + + + template + Teuchos::RCP< + const Tpetra::Vector> + Vector::trilinos_rcp() const + { + return vector.getConst(); + } + + + template void Vector::print(std::ostream &out, @@ -668,6 +730,22 @@ namespace LinearAlgebra } + template + const MPI_Comm + Vector::mpi_comm() const + { + MPI_Comm out; +# ifdef DEAL_II_WITH_MPI + const Teuchos::MpiComm *mpi_comm = + dynamic_cast *>( + vector->getMap()->getComm().get()); + out = *mpi_comm->getRawMpiComm(); +# else + out = MPI_COMM_SELF; +# endif + return out; + } + template std::size_t @@ -686,9 +764,10 @@ namespace LinearAlgebra const MPI_Comm mpi_comm) { source_stored_elements = source_index_set; + tpetra_comm_pattern = - std::make_shared( - locally_owned_elements(), source_index_set, mpi_comm); + Teuchos::rcp(new TpetraWrappers::CommunicationPattern( + locally_owned_elements(), source_index_set, mpi_comm)); } } // namespace TpetraWrappers } // namespace LinearAlgebra diff --git a/source/lac/trilinos_tpetra_communication_pattern.cc b/source/lac/trilinos_tpetra_communication_pattern.cc index b52585fe46..9a462334a3 100644 --- a/source/lac/trilinos_tpetra_communication_pattern.cc +++ b/source/lac/trilinos_tpetra_communication_pattern.cc @@ -49,7 +49,7 @@ namespace LinearAlgebra const IndexSet &ghost_indices, const MPI_Comm communicator) { - comm = std::make_shared(communicator); + comm = Teuchos::rcpFromRef(communicator); auto vector_space_vector_map = locally_owned_indices.make_tpetra_map_rcp(*comm, false); @@ -60,11 +60,11 @@ namespace LinearAlgebra // Source map is vector_space_vector_map. This map must have uniquely // owned GID. tpetra_import = - std::make_unique>( - read_write_vector_map, vector_space_vector_map); + Teuchos::rcp(new Tpetra::Import( + read_write_vector_map, vector_space_vector_map)); tpetra_export = - std::make_unique>( - read_write_vector_map, vector_space_vector_map); + Teuchos::rcp(new Tpetra::Export( + read_write_vector_map, vector_space_vector_map)); } @@ -85,11 +85,27 @@ namespace LinearAlgebra + Teuchos::RCP> + CommunicationPattern::get_tpetra_import_rcp() const + { + return tpetra_import; + } + + + const Tpetra::Export & CommunicationPattern::get_tpetra_export() const { return *tpetra_export; } + + + + Teuchos::RCP> + CommunicationPattern::get_tpetra_export_rcp() const + { + return tpetra_export; + } } // namespace TpetraWrappers } // namespace LinearAlgebra