]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add generic constructor for TrilinosPayload
authorJean-Paul Pelteret <jppelteret@gmail.com>
Tue, 14 Sep 2021 19:32:04 +0000 (21:32 +0200)
committerJean-Paul Pelteret <jppelteret@gmail.com>
Tue, 14 Sep 2021 19:32:34 +0000 (21:32 +0200)
include/deal.II/lac/trilinos_sparse_matrix.h
source/lac/trilinos_sparse_matrix.cc

index d9c33137f31f4022eac762ae15a169ce8eaaafea..ace7ab1a98e24953e0ea1a5159d3f2202ee2ebec 100644 (file)
@@ -2387,6 +2387,23 @@ namespace TrilinosWrappers
         //@}
 
       private:
+        /**
+         * A generic constructor.
+         *
+         * This constructor allows the payload to be configured from any
+         * objects that can be cast to an Epetra operation. The
+         * @p supports_inverse_operations flag indicates that the
+         * @p op can be used to compute inverse operations; preconditioners
+         * have such a facility.
+         */
+        template <typename EpetraOpType>
+        TrilinosPayload(EpetraOpType &  op,
+                        const bool      supports_inverse_operations,
+                        const bool      use_transpose,
+                        const MPI_Comm &mpi_communicator,
+                        const IndexSet &locally_owned_domain_indices,
+                        const IndexSet &locally_owned_range_indices);
+
         /**
          * A flag recording whether the operator is to perform standard
          * matrix-vector multiplication, or the transpose operation.
@@ -3078,6 +3095,104 @@ namespace TrilinosWrappers
   {
     namespace LinearOperatorImplementation
     {
+      template <typename EpetraOpType>
+      TrilinosPayload::TrilinosPayload(
+        EpetraOpType &  op,
+        const bool      supports_inverse_operations,
+        const bool      use_transpose,
+        const MPI_Comm &mpi_communicator,
+        const IndexSet &locally_owned_domain_indices,
+        const IndexSet &locally_owned_range_indices)
+        : use_transpose(use_transpose)
+        , communicator(mpi_communicator)
+        , domain_map(
+            locally_owned_domain_indices.make_trilinos_map(communicator.Comm()))
+        , range_map(
+            locally_owned_range_indices.make_trilinos_map(communicator.Comm()))
+      {
+        vmult = [&op](Range &tril_dst, const Domain &tril_src) {
+          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
+          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
+          Assert(&tril_src != &tril_dst,
+                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
+          internal::check_vector_map_equality(op,
+                                              tril_src,
+                                              tril_dst,
+                                              op.UseTranspose());
+
+          const int ierr = op.Apply(tril_src, tril_dst);
+          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
+        };
+
+        Tvmult = [&op](Domain &tril_dst, const Range &tril_src) {
+          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
+          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
+          Assert(&tril_src != &tril_dst,
+                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
+          internal::check_vector_map_equality(op,
+                                              tril_src,
+                                              tril_dst,
+                                              !op.UseTranspose());
+
+          op.SetUseTranspose(!op.UseTranspose());
+          const int ierr = op.Apply(tril_src, tril_dst);
+          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
+          op.SetUseTranspose(!op.UseTranspose());
+        };
+
+        if (supports_inverse_operations)
+          {
+            inv_vmult = [&op](Domain &tril_dst, const Range &tril_src) {
+              // Duplicated from TrilinosWrappers::PreconditionBase::vmult
+              // as well as from TrilinosWrappers::SparseMatrix::Tvmult
+              Assert(
+                &tril_src != &tril_dst,
+                TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
+              internal::check_vector_map_equality(op,
+                                                  tril_src,
+                                                  tril_dst,
+                                                  !op.UseTranspose());
+
+              const int ierr = op.ApplyInverse(tril_src, tril_dst);
+              AssertThrow(ierr == 0, ExcTrilinosError(ierr));
+            };
+
+            inv_Tvmult = [&op](Range &tril_dst, const Domain &tril_src) {
+              // Duplicated from TrilinosWrappers::PreconditionBase::vmult
+              // as well as from TrilinosWrappers::SparseMatrix::Tvmult
+              Assert(
+                &tril_src != &tril_dst,
+                TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
+              internal::check_vector_map_equality(op,
+                                                  tril_src,
+                                                  tril_dst,
+                                                  op.UseTranspose());
+
+              op.SetUseTranspose(!op.UseTranspose());
+              const int ierr = op.ApplyInverse(tril_src, tril_dst);
+              AssertThrow(ierr == 0, ExcTrilinosError(ierr));
+              op.SetUseTranspose(!op.UseTranspose());
+            };
+          }
+        else
+          {
+            inv_vmult = [](Domain &, const Range &) {
+              Assert(false,
+                     ExcMessage(
+                       "Uninitialized TrilinosPayload::inv_vmult called. "
+                       "The operator does not support inverse operations."));
+            };
+
+            inv_Tvmult = [](Range &, const Domain &) {
+              Assert(false,
+                     ExcMessage(
+                       "Uninitialized TrilinosPayload::inv_Tvmult called. "
+                       "The operator does not support inverse operations."));
+            };
+          }
+      }
+
+
       template <typename Solver, typename Preconditioner>
       typename std::enable_if<
         std::is_base_of<TrilinosWrappers::SolverBase, Solver>::value &&
index ad7864f12a2b3cb3acc487fe868c8839fb382003..1b20186c533e25ed353a82ccb399c75f75463087 100644 (file)
@@ -2354,483 +2354,69 @@ namespace TrilinosWrappers
       TrilinosPayload::TrilinosPayload(
         const TrilinosWrappers::SparseMatrix &matrix_exemplar,
         const TrilinosWrappers::SparseMatrix &matrix)
-        : use_transpose(matrix_exemplar.trilinos_matrix().UseTranspose())
-        , communicator(matrix_exemplar.get_mpi_communicator())
-        , domain_map(
-            matrix_exemplar.locally_owned_domain_indices().make_trilinos_map(
-              communicator.Comm()))
-        , range_map(
-            matrix_exemplar.locally_owned_range_indices().make_trilinos_map(
-              communicator.Comm()))
-      {
-        vmult = [&matrix_exemplar, &matrix](Range &       tril_dst,
-                                            const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::SparseMatrix::vmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          Assert(matrix.trilinos_matrix().Filled(),
-                 TrilinosWrappers::SparseMatrix::ExcMatrixNotCompressed());
-          internal::check_vector_map_equality(
-            matrix_exemplar.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            matrix_exemplar.trilinos_matrix().UseTranspose());
-          internal::check_vector_map_equality(
-            matrix.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            matrix.trilinos_matrix().UseTranspose());
-
-          const int ierr = matrix.trilinos_matrix().Apply(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
-
-        Tvmult = [&matrix_exemplar, &matrix](Domain &     tril_dst,
-                                             const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          Assert(matrix.trilinos_matrix().Filled(),
-                 TrilinosWrappers::SparseMatrix::ExcMatrixNotCompressed());
-          internal::check_vector_map_equality(
-            matrix_exemplar.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            !matrix_exemplar.trilinos_matrix().UseTranspose());
-          internal::check_vector_map_equality(
-            matrix.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            !matrix.trilinos_matrix().UseTranspose());
-
-          Epetra_CrsMatrix &tril_mtrx_non_const =
-            const_cast<Epetra_CrsMatrix &>(matrix.trilinos_matrix());
-          tril_mtrx_non_const.SetUseTranspose(
-            !matrix.trilinos_matrix().UseTranspose());
-          const int ierr = matrix.trilinos_matrix().Apply(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          tril_mtrx_non_const.SetUseTranspose(
-            !matrix.trilinos_matrix().UseTranspose());
-        };
-
-        inv_vmult = [](Domain &, const Range &) {
-          Assert(false,
-                 ExcMessage("Uninitialized TrilinosPayload::inv_vmult called "
-                            "(Matrix constructor with matrix exemplar)"));
-        };
-
-        inv_Tvmult = [](Range &, const Domain &) {
-          Assert(false,
-                 ExcMessage("Uninitialized TrilinosPayload::inv_Tvmult called "
-                            "(Matrix constructor with matrix exemplar)"));
-        };
-      }
+        : TrilinosPayload(const_cast<Epetra_CrsMatrix &>(
+                            matrix.trilinos_matrix()),
+                          /*op_supports_inverse_operations = */ false,
+                          matrix_exemplar.trilinos_matrix().UseTranspose(),
+                          matrix_exemplar.get_mpi_communicator(),
+                          matrix_exemplar.locally_owned_domain_indices(),
+                          matrix_exemplar.locally_owned_range_indices())
+      {}
 
 
 
       TrilinosPayload::TrilinosPayload(
         const TrilinosPayload &               payload_exemplar,
         const TrilinosWrappers::SparseMatrix &matrix)
-        : use_transpose(payload_exemplar.UseTranspose())
-        , communicator(payload_exemplar.get_mpi_communicator())
-        , domain_map(
-            payload_exemplar.locally_owned_domain_indices().make_trilinos_map(
-              communicator.Comm()))
-        , range_map(
-            payload_exemplar.locally_owned_range_indices().make_trilinos_map(
-              communicator.Comm()))
-      {
-        vmult = [&payload_exemplar, &matrix](Range &       tril_dst,
-                                             const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::SparseMatrix::vmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          Assert(matrix.trilinos_matrix().Filled(),
-                 TrilinosWrappers::SparseMatrix::ExcMatrixNotCompressed());
-          internal::check_vector_map_equality(payload_exemplar,
-                                              tril_src,
-                                              tril_dst,
-                                              payload_exemplar.UseTranspose());
-          internal::check_vector_map_equality(
-            matrix.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            matrix.trilinos_matrix().UseTranspose());
-
-          const int ierr = matrix.trilinos_matrix().Apply(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
 
-        Tvmult = [&payload_exemplar, &matrix](Domain &     tril_dst,
-                                              const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          Assert(matrix.trilinos_matrix().Filled(),
-                 TrilinosWrappers::SparseMatrix::ExcMatrixNotCompressed());
-          internal::check_vector_map_equality(payload_exemplar,
-                                              tril_src,
-                                              tril_dst,
-                                              !payload_exemplar.UseTranspose());
-          internal::check_vector_map_equality(
-            matrix.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            !matrix.trilinos_matrix().UseTranspose());
-
-          Epetra_CrsMatrix &tril_mtrx_non_const =
-            const_cast<Epetra_CrsMatrix &>(matrix.trilinos_matrix());
-          tril_mtrx_non_const.SetUseTranspose(
-            !matrix.trilinos_matrix().UseTranspose());
-          const int ierr = matrix.trilinos_matrix().Apply(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          tril_mtrx_non_const.SetUseTranspose(
-            !matrix.trilinos_matrix().UseTranspose());
-        };
-
-        inv_vmult = [](Domain &, const Range &) {
-          Assert(false,
-                 ExcMessage("Uninitialized TrilinosPayload::inv_vmult called "
-                            "(Matrix constructor with matrix exemplar)"));
-        };
-
-        inv_Tvmult = [](Range &, const Domain &) {
-          Assert(false,
-                 ExcMessage("Uninitialized TrilinosPayload::inv_Tvmult called "
-                            "(Matrix constructor with matrix exemplar)"));
-        };
-      }
+        : TrilinosPayload(const_cast<Epetra_CrsMatrix &>(
+                            matrix.trilinos_matrix()),
+                          /*op_supports_inverse_operations = */ false,
+                          payload_exemplar.UseTranspose(),
+                          payload_exemplar.get_mpi_communicator(),
+                          payload_exemplar.locally_owned_domain_indices(),
+                          payload_exemplar.locally_owned_range_indices())
+      {}
 
 
 
       TrilinosPayload::TrilinosPayload(
         const TrilinosWrappers::SparseMatrix &    matrix_exemplar,
         const TrilinosWrappers::PreconditionBase &preconditioner)
-        : use_transpose(matrix_exemplar.trilinos_matrix().UseTranspose())
-        , communicator(matrix_exemplar.get_mpi_communicator())
-        , domain_map(
-            matrix_exemplar.locally_owned_domain_indices().make_trilinos_map(
-              communicator.Comm()))
-        , range_map(
-            matrix_exemplar.locally_owned_range_indices().make_trilinos_map(
-              communicator.Comm()))
-      {
-        vmult = [&matrix_exemplar, &preconditioner](Range &       tril_dst,
-                                                    const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            matrix_exemplar.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            matrix_exemplar.trilinos_matrix().UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner.trilinos_operator().UseTranspose());
-
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
-
-        Tvmult = [&matrix_exemplar, &preconditioner](Domain &     tril_dst,
-                                                     const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            matrix_exemplar.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            !matrix_exemplar.trilinos_matrix().UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner.trilinos_operator().UseTranspose());
-
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-        };
-
-        inv_vmult = [&matrix_exemplar, &preconditioner](Domain &     tril_dst,
-                                                        const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            matrix_exemplar.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            !matrix_exemplar.trilinos_matrix().UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner.trilinos_operator().UseTranspose());
-
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
-
-        inv_Tvmult = [&matrix_exemplar,
-                      &preconditioner](Range &       tril_dst,
-                                       const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            matrix_exemplar.trilinos_matrix(),
-            tril_src,
-            tril_dst,
-            matrix_exemplar.trilinos_matrix().UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner.trilinos_operator().UseTranspose());
-
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-        };
-      }
+        : TrilinosPayload(preconditioner.trilinos_operator(),
+                          /*op_supports_inverse_operations = */ true,
+                          matrix_exemplar.trilinos_matrix().UseTranspose(),
+                          matrix_exemplar.get_mpi_communicator(),
+                          matrix_exemplar.locally_owned_domain_indices(),
+                          matrix_exemplar.locally_owned_range_indices())
+      {}
 
 
 
       TrilinosPayload::TrilinosPayload(
         const TrilinosWrappers::PreconditionBase &preconditioner_exemplar,
         const TrilinosWrappers::PreconditionBase &preconditioner)
-        : use_transpose(
-            preconditioner_exemplar.trilinos_operator().UseTranspose())
-        , communicator(preconditioner_exemplar.get_mpi_communicator())
-        , domain_map(preconditioner_exemplar.locally_owned_domain_indices()
-                       .make_trilinos_map(communicator.Comm()))
-        , range_map(preconditioner_exemplar.locally_owned_range_indices()
-                      .make_trilinos_map(communicator.Comm()))
-      {
-        vmult = [&preconditioner_exemplar,
-                 &preconditioner](Range &tril_dst, const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            preconditioner_exemplar.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner_exemplar.trilinos_operator().UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner.trilinos_operator().UseTranspose());
-
-          const int ierr =
-            preconditioner.trilinos_operator().Apply(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
-
-        Tvmult = [&preconditioner_exemplar,
-                  &preconditioner](Domain &tril_dst, const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            preconditioner_exemplar.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner_exemplar.trilinos_operator().UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner.trilinos_operator().UseTranspose());
-
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-          const int ierr =
-            preconditioner.trilinos_operator().Apply(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-        };
-
-        inv_vmult = [&preconditioner_exemplar,
-                     &preconditioner](Domain &tril_dst, const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            preconditioner_exemplar.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner_exemplar.trilinos_operator().UseTranspose());
-          internal::check_vector_map_equality(
+        : TrilinosPayload(
             preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner.trilinos_operator().UseTranspose());
-
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
-
-        inv_Tvmult = [&preconditioner_exemplar,
-                      &preconditioner](Range &       tril_dst,
-                                       const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(
-            preconditioner_exemplar.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner_exemplar.trilinos_operator().UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner.trilinos_operator().UseTranspose());
-
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-        };
-      }
+            /*op_supports_inverse_operations = */ true,
+            preconditioner_exemplar.trilinos_operator().UseTranspose(),
+            preconditioner_exemplar.get_mpi_communicator(),
+            preconditioner_exemplar.locally_owned_domain_indices(),
+            preconditioner_exemplar.locally_owned_range_indices())
+      {}
 
 
 
       TrilinosPayload::TrilinosPayload(
         const TrilinosPayload &                   payload_exemplar,
         const TrilinosWrappers::PreconditionBase &preconditioner)
-        : use_transpose(payload_exemplar.UseTranspose())
-        , communicator(payload_exemplar.get_mpi_communicator())
-        , domain_map(
-            payload_exemplar.locally_owned_domain_indices().make_trilinos_map(
-              communicator.Comm()))
-        , range_map(
-            payload_exemplar.locally_owned_range_indices().make_trilinos_map(
-              communicator.Comm()))
-      {
-        vmult = [&payload_exemplar, &preconditioner](Range &       tril_dst,
-                                                     const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(payload_exemplar,
-                                              tril_src,
-                                              tril_dst,
-                                              payload_exemplar.UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner.trilinos_operator().UseTranspose());
-
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
-
-        Tvmult = [&payload_exemplar, &preconditioner](Domain &     tril_dst,
-                                                      const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(payload_exemplar,
-                                              tril_src,
-                                              tril_dst,
-                                              !payload_exemplar.UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner.trilinos_operator().UseTranspose());
-
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-        };
-
-        inv_vmult = [&payload_exemplar,
-                     &preconditioner](Domain &tril_dst, const Range &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(payload_exemplar,
-                                              tril_src,
-                                              tril_dst,
-                                              !payload_exemplar.UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            !preconditioner.trilinos_operator().UseTranspose());
-
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-        };
-
-        inv_Tvmult = [&payload_exemplar,
-                      &preconditioner](Range &       tril_dst,
-                                       const Domain &tril_src) {
-          // Duplicated from TrilinosWrappers::PreconditionBase::vmult
-          // as well as from TrilinosWrappers::SparseMatrix::Tvmult
-          Assert(&tril_src != &tril_dst,
-                 TrilinosWrappers::SparseMatrix::ExcSourceEqualsDestination());
-          internal::check_vector_map_equality(payload_exemplar,
-                                              tril_src,
-                                              tril_dst,
-                                              payload_exemplar.UseTranspose());
-          internal::check_vector_map_equality(
-            preconditioner.trilinos_operator(),
-            tril_src,
-            tril_dst,
-            preconditioner.trilinos_operator().UseTranspose());
-
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-          const int ierr =
-            preconditioner.trilinos_operator().ApplyInverse(tril_src, tril_dst);
-          AssertThrow(ierr == 0, ExcTrilinosError(ierr));
-          preconditioner.trilinos_operator().SetUseTranspose(
-            !preconditioner.trilinos_operator().UseTranspose());
-        };
-      }
+        : TrilinosPayload(preconditioner.trilinos_operator(),
+                          /*op_supports_inverse_operations = */ true,
+                          payload_exemplar.UseTranspose(),
+                          payload_exemplar.get_mpi_communicator(),
+                          payload_exemplar.locally_owned_domain_indices(),
+                          payload_exemplar.locally_owned_range_indices())
+      {}
 
 
 

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.