]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Qualify TpetraWrappers::Vectors for use with AffineConstraints. 16156/head
authorSebastian Kinnewig <kinnewig@ifam.uni-hannover.de>
Tue, 17 Oct 2023 14:24:40 +0000 (16:24 +0200)
committerSebastian Kinnewig <kinnewig@ifam.uni-hannover.de>
Thu, 26 Oct 2023 10:01:27 +0000 (12:01 +0200)
doc/news/changes/minor/20231018SebastianKinnewig [new file with mode: 0644]
include/deal.II/lac/trilinos_tpetra_communication_pattern.h
include/deal.II/lac/trilinos_tpetra_vector.h
include/deal.II/lac/trilinos_tpetra_vector.templates.h
source/lac/trilinos_tpetra_communication_pattern.cc

diff --git a/doc/news/changes/minor/20231018SebastianKinnewig b/doc/news/changes/minor/20231018SebastianKinnewig
new file mode 100644 (file)
index 0000000..54bf0e0
--- /dev/null
@@ -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.
+<br>
+(Sebastian Kinnewig, 2023/10/18)
index a759cf9ed57b6f5d39e4e9ab5edebf91a6f4d83d..9a88e53faadceb617278c92499706c40a05c750c 100644 (file)
@@ -87,28 +87,40 @@ namespace LinearAlgebra
       const Tpetra::Import<int, types::signed_global_dof_index> &
       get_tpetra_import() const;
 
+      /**
+       * Return a Teuchos::RCP to the underlying Tpetra::Import object.
+       */
+      Teuchos::RCP<const Tpetra::Import<int, types::signed_global_dof_index>>
+      get_tpetra_import_rcp() const;
+
       /**
        * Return the underlying Tpetra::Export object.
        */
       const Tpetra::Export<int, types::signed_global_dof_index> &
       get_tpetra_export() const;
 
+      /**
+       * Return a Teuchos::RCP to the underlying Tpetra::Export object.
+       */
+      Teuchos::RCP<const Tpetra::Export<int, types::signed_global_dof_index>>
+      get_tpetra_export_rcp() const;
+
     private:
       /**
-       * Shared pointer to the MPI communicator used.
+       * Teuchos::RCP to the MPI communicator used.
        */
-      std::shared_ptr<const MPI_Comm> comm;
+      Teuchos::RCP<const MPI_Comm> comm;
 
       /**
-       * Shared pointer to the Tpetra::Import object used.
+       * Teuchos::RCP to the Tpetra::Import object used.
        */
-      std::unique_ptr<Tpetra::Import<int, types::signed_global_dof_index>>
+      Teuchos::RCP<Tpetra::Import<int, types::signed_global_dof_index>>
         tpetra_import;
 
       /**
-       * Shared pointer to the Tpetra::Export object used.
+       * Teuchos::RCP to the Tpetra::Export object used.
        */
-      std::unique_ptr<Tpetra::Export<int, types::signed_global_dof_index>>
+      Teuchos::RCP<Tpetra::Export<int, types::signed_global_dof_index>>
         tpetra_export;
     };
   } // end of namespace TpetraWrappers
index faa6f84026663406307d19c43d6b90eb37ea9c0e..e53d38d15cb7b1baba72cb14382da9598531710a 100644 (file)
@@ -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 <typename Number>
+      class VectorReference
+      {
+      private:
+        /**
+         * Constructor. It is made private so as to only allow the actual vector
+         * class to create it.
+         */
+        VectorReference(Vector<Number> &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 <tt>v(i)=w(i)</tt>. 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 <tt>s</tt>.
+         */
+        const VectorReference &
+        operator=(const Number &s) const;
+
+        /**
+         * Add <tt>s</tt> to the referenced element of the vector->
+         */
+        const VectorReference &
+        operator+=(const Number &s) const;
+
+        /**
+         * Subtract <tt>s</tt> from the referenced element of the vector->
+         */
+        const VectorReference &
+        operator-=(const Number &s) const;
+
+        /**
+         * Multiply the referenced element of the vector by <tt>s</tt>.
+         */
+        const VectorReference &
+        operator*=(const Number &s) const;
+
+        /**
+         * Divide the referenced element of the vector by <tt>s</tt>.
+         */
+        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<Number> &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<Number>;
+      }; // 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 <typename Number>
     class Vector : public ReadVector<Number>, public Subscriptor
     {
     public:
+      /**
+       * Declare some of the standard types used in all containers.
+       */
       using value_type = Number;
       using real_type  = typename numbers::NumberTraits<Number>::real_type;
       using size_type  = types::global_dof_index;
+      using reference  = internal::VectorReference<Number>;
+      using MapType = Tpetra::Map<int, dealii::types::signed_global_dof_index>;
+      using VectorType =
+        Tpetra::Vector<Number, int, dealii::types::signed_global_dof_index>;
 
       /**
-       * Constructor. Create a vector of dimension zero.
+       * @name 1: Basic Object-handling
+       */
+      /** @{ */
+      /**
+       * Default constructor that generates an empty (zero size) vector. The
+       * function <tt>reinit()</tt> 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<Tpetra::Vector>.
+       */
+      Vector(const Teuchos::RCP<VectorType> 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<Number> &V,
+        VectorOperation::values        operation,
+        const Teuchos::RCP<const Utilities::MPI::CommunicationPatternBase>
+          &communication_pattern);
+
+      /**
+       * @deprecated Use Teuchos::RCP<> instead of std::shared_ptr<>.
+       */
+      DEAL_II_DEPRECATED
+      void
       import_elements(
         const ReadWriteVector<Number> &V,
         VectorOperation::values        operation,
         const std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
-          &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<Number> &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<Number> &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<size_type>      &indices,
+          const std::vector<TrilinosScalar> &values);
+
+
+      /**
+       * Take an address where <tt>n_elements</tt> are stored contiguously and
+       * add them into the vector. Handles all cases which are not covered by
+       * the other two <tt>add()</tt> 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. <tt>*this
        * = s*(*this)+a*V</tt>.
@@ -269,6 +508,17 @@ namespace LinearAlgebra
       void
       sadd(const Number s, const Number a, const Vector<Number> &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<Number> &V,
                   const Vector<Number> &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<Number, int, types::signed_global_dof_index> &
       trilinos_vector();
 
+      /**
+       * Return a const Teuchos::RCP to the underlying Trilinos
+       * Tpetra::Vector class.
+       */
+      Teuchos::RCP<
+        const Tpetra::Vector<Number, int, types::signed_global_dof_index>>
+      trilinos_rcp() const;
+
+      /**
+       * Return a (modifiable) Teuchos::RCP to the underlying Trilinos
+       * Tpetra::Vector class.
+       */
+      Teuchos::RCP<Tpetra::Vector<Number, int, types::signed_global_dof_index>>
+      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<Number, int, types::signed_global_dof_index>>
-        vector;
+      Teuchos::RCP<VectorType> 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<const TpetraWrappers::CommunicationPattern>
+      Teuchos::RCP<const TpetraWrappers::CommunicationPattern>
         tpetra_comm_pattern;
+
+      // Make the reference class a friend.
+      friend class internal::VectorReference<Number>;
     };
 
 
+    /* ------------------------- Inline functions ---------------------- */
+
     template <typename Number>
     inline bool
     Vector<Number>::has_ghost_elements() const
     {
       return false;
     }
+
+
+
+    template <typename Number>
+    inline void
+    Vector<Number>::add(const std::vector<size_type>      &indices,
+                        const std::vector<TrilinosScalar> &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 <typename Number>
+    inline void
+    Vector<Number>::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<Kokkos::HostSpace>(
+        Tpetra::Access::ReadWrite);
+#  else
+      vector->template sync<Kokkos::HostSpace>();
+      auto vector_2d = vector.template getLocalView<Kokkos::HostSpace>();
+#  endif
+      auto vector_1d = Kokkos::subview(vector_2d, Kokkos::ALL(), 0);
+#  if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
+      vector->template modify<Kokkos::HostSpace>();
+#  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<int>::invalid())
+            vector_1d(local_row) += values[i];
+        }
+
+#  if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
+      vector->template sync<
+        typename Tpetra::Vector<Number, int, types::signed_global_dof_index>::
+          device_type::memory_space>();
+#  endif
+    }
+
+
+
+    template <typename Number>
+    inline void
+    Vector<Number>::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<Kokkos::HostSpace>(
+        Tpetra::Access::ReadWrite);
+#  else
+      vector->template sync<Kokkos::HostSpace>();
+      auto vector_2d = vector->template getLocalView<Kokkos::HostSpace>();
+#  endif
+      auto vector_1d = Kokkos::subview(vector_2d, Kokkos::ALL(), 0);
+#  if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
+      vector->template modify<Kokkos::HostSpace>();
+#  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<int>::invalid())
+            vector_1d(local_row) = values[i];
+        }
+
+#  if !DEAL_II_TRILINOS_VERSION_GTE(13, 2, 0)
+      vector->template sync<
+        typename Tpetra::Vector<Number, int, types::signed_global_dof_index>::
+          device_type::memory_space>();
+#  endif
+    }
+
+
+
+    template <typename Number>
+    inline internal::VectorReference<Number>
+    Vector<Number>::operator()(const size_type index)
+    {
+      return internal::VectorReference(*this, index);
+    }
+
+#  ifndef DOXYGEN
+
+    // VectorReference
+    namespace internal
+    {
+      template <typename Number>
+      inline VectorReference<Number>::VectorReference(Vector<Number> &vector,
+                                                      const size_type index)
+        : vector(vector)
+        , index(index)
+      {}
+
+
+
+      template <typename Number>
+      inline const VectorReference<Number> &
+      VectorReference<Number>::operator=(const VectorReference<Number> &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<Number>(r);
+
+        return *this;
+      }
+
+
+
+      template <typename Number>
+      inline VectorReference<Number> &
+      VectorReference<Number>::operator=(const VectorReference<Number> &r)
+      {
+        // as above
+        *this = static_cast<Number>(r);
+
+        return *this;
+      }
+
+
+
+      template <typename Number>
+      inline const VectorReference<Number> &
+      VectorReference<Number>::operator=(const Number &value) const
+      {
+        vector.set(1, &index, &value);
+        return *this;
+      }
+
+
+
+      template <typename Number>
+      inline const VectorReference<Number> &
+      VectorReference<Number>::operator+=(const Number &value) const
+      {
+        vector.add(1, &index, &value);
+        return *this;
+      }
+
+
+
+      template <typename Number>
+      inline const VectorReference<Number> &
+      VectorReference<Number>::operator-=(const Number &value) const
+      {
+        Number new_value = -value;
+        vector.add(1, &index, &new_value);
+        return *this;
+      }
+
+
+
+      template <typename Number>
+      inline const VectorReference<Number> &
+      VectorReference<Number>::operator*=(const Number &value) const
+      {
+        Number new_value = static_cast<Number>(*this) * value;
+        vector.set(1, &index, &new_value);
+        return *this;
+      }
+
+
+
+      template <typename Number>
+      inline const VectorReference<Number> &
+      VectorReference<Number>::operator/=(const Number &value) const
+      {
+        Number new_value = static_cast<Number>(*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.
index 1d5c78161bea1271def927e649132feb0598118f..eccc2f41eeef926388c4569af55741615b94547b 100644 (file)
@@ -47,12 +47,8 @@ namespace LinearAlgebra
     template <typename Number>
     Vector<Number>::Vector()
       : Subscriptor()
-      , vector(new Tpetra::Vector<Number, int, types::signed_global_dof_index>(
-          Teuchos::RCP<Tpetra::Map<int, types::signed_global_dof_index>>(
-            new Tpetra::Map<int, types::signed_global_dof_index>(
-              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 <typename Number>
     Vector<Number>::Vector(const Vector<Number> &V)
       : Subscriptor()
-      , vector(new Tpetra::Vector<Number, int, types::signed_global_dof_index>(
-          V.trilinos_vector(),
-          Teuchos::Copy))
+      , vector(new VectorType(V.trilinos_vector(), Teuchos::Copy))
+    {}
+
+
+
+    template <typename Number>
+    Vector<Number>::Vector(const Teuchos::RCP<VectorType> V)
+      : Subscriptor()
+      , vector(V)
     {}
 
 
@@ -71,7 +73,7 @@ namespace LinearAlgebra
     Vector<Number>::Vector(const IndexSet &parallel_partitioner,
                            const MPI_Comm  communicator)
       : Subscriptor()
-      , vector(new Tpetra::Vector<Number, int, types::signed_global_dof_index>(
+      , 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<Tpetra::Map<int, types::signed_global_dof_index>> input_map =
+      Teuchos::RCP<MapType> input_map =
         parallel_partitioner.make_tpetra_map_rcp(communicator, false);
+
       if (vector->getMap()->isSameAs(*input_map) == false)
-        vector = std::make_unique<
-          Tpetra::Vector<Number, int, types::signed_global_dof_index>>(
-          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 <typename Number>
+    void
+    Vector<Number>::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<MapType> input_map =
+        parallel_partitioner.make_tpetra_map_rcp(communicator, true);
+
+      vector = Teuchos::rcp(new VectorType(input_map));
+    }
+
+
+
     template <typename Number>
     void
     Vector<Number>::reinit(const Vector<Number> &V,
@@ -170,9 +188,7 @@ namespace LinearAlgebra
                                Tpetra::REPLACE);
             }
           else
-            vector = std::make_unique<
-              Tpetra::Vector<Number, int, types::signed_global_dof_index>>(
-              V.trilinos_vector());
+            vector = Teuchos::rcp(new VectorType(V.trilinos_vector()));
         }
 
       return *this;
@@ -199,12 +215,12 @@ namespace LinearAlgebra
     Vector<Number>::import_elements(
       const ReadWriteVector<Number> &V,
       VectorOperation::values        operation,
-      const std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
+      const Teuchos::RCP<const Utilities::MPI::CommunicationPatternBase>
         &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<int, types::signed_global_dof_index> tpetra_export(
-        tpetra_comm_pattern->get_tpetra_export());
-      Tpetra::Vector<Number, int, types::signed_global_dof_index> source_vector(
-        tpetra_export.getSourceMap());
+      Teuchos::RCP<const Tpetra::Export<int, types::signed_global_dof_index>>
+        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 <typename Number>
+    void
+    Vector<Number>::import_elements(
+      const ReadWriteVector<Number> &V,
+      VectorOperation::values        operation,
+      const std::shared_ptr<const Utilities::MPI::CommunicationPatternBase>
+        &communication_pattern)
+    {
+      import_elements(V, operation);
+    }
+
+
+    template <typename Number>
+    void
+    Vector<Number>::import_elements(const ReadWriteVector<Number> &V,
+                                    VectorOperation::values        operation)
+    {
+      // Create an empty CommunicationPattern
+      const Teuchos::RCP<const Utilities::MPI::CommunicationPatternBase>
+        communication_pattern_empty;
+
+      import_elements(V, operation, communication_pattern_empty);
+    }
+
+
+
     template <typename Number>
     Vector<Number> &
     Vector<Number>::operator*=(const Number factor)
@@ -624,6 +667,25 @@ namespace LinearAlgebra
 
 
 
+    template <typename Number>
+    Teuchos::RCP<Tpetra::Vector<Number, int, types::signed_global_dof_index>>
+    Vector<Number>::trilinos_rcp()
+    {
+      return vector;
+    }
+
+
+
+    template <typename Number>
+    Teuchos::RCP<
+      const Tpetra::Vector<Number, int, types::signed_global_dof_index>>
+    Vector<Number>::trilinos_rcp() const
+    {
+      return vector.getConst();
+    }
+
+
+
     template <typename Number>
     void
     Vector<Number>::print(std::ostream      &out,
@@ -668,6 +730,22 @@ namespace LinearAlgebra
     }
 
 
+    template <typename Number>
+    const MPI_Comm
+    Vector<Number>::mpi_comm() const
+    {
+      MPI_Comm out;
+#  ifdef DEAL_II_WITH_MPI
+      const Teuchos::MpiComm<int> *mpi_comm =
+        dynamic_cast<const Teuchos::MpiComm<int> *>(
+          vector->getMap()->getComm().get());
+      out = *mpi_comm->getRawMpiComm();
+#  else
+      out            = MPI_COMM_SELF;
+#  endif
+      return out;
+    }
+
 
     template <typename Number>
     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<TpetraWrappers::CommunicationPattern>(
-          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
index b52585fe46def39476a4998529c75778fc81ef8b..9a462334a3080f542613fe9b25b4935cdc44e3a5 100644 (file)
@@ -49,7 +49,7 @@ namespace LinearAlgebra
                                  const IndexSet &ghost_indices,
                                  const MPI_Comm  communicator)
     {
-      comm = std::make_shared<const MPI_Comm>(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<Tpetra::Import<int, types::signed_global_dof_index>>(
-          read_write_vector_map, vector_space_vector_map);
+        Teuchos::rcp(new Tpetra::Import<int, types::signed_global_dof_index>(
+          read_write_vector_map, vector_space_vector_map));
       tpetra_export =
-        std::make_unique<Tpetra::Export<int, types::signed_global_dof_index>>(
-          read_write_vector_map, vector_space_vector_map);
+        Teuchos::rcp(new Tpetra::Export<int, types::signed_global_dof_index>(
+          read_write_vector_map, vector_space_vector_map));
     }
 
 
@@ -85,11 +85,27 @@ namespace LinearAlgebra
 
 
 
+    Teuchos::RCP<const Tpetra::Import<int, types::signed_global_dof_index>>
+    CommunicationPattern::get_tpetra_import_rcp() const
+    {
+      return tpetra_import;
+    }
+
+
+
     const Tpetra::Export<int, types::signed_global_dof_index> &
     CommunicationPattern::get_tpetra_export() const
     {
       return *tpetra_export;
     }
+
+
+
+    Teuchos::RCP<const Tpetra::Export<int, types::signed_global_dof_index>>
+    CommunicationPattern::get_tpetra_export_rcp() const
+    {
+      return tpetra_export;
+    }
   } // namespace TpetraWrappers
 } // namespace LinearAlgebra
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.