class ReinitHelper<LinearAlgebra::distributed::Vector<Number>>
{
public:
- template <typename Matrix>
+ // A helper type-trait that leverage SFINAE to figure out if type T has
+ // void T::get_mpi_communicator()
+ template <typename T>
+ struct has_get_mpi_communicator
+ {
+ private:
+ static bool
+ detect(...);
+
+ template <typename U>
+ static decltype(std::declval<U>().get_mpi_communicator())
+ detect(const U &);
+
+ public:
+ static const bool value =
+ !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
+ };
+
+ // A helper type-trait that leverage SFINAE to figure out if type T has
+ // void T::locally_owned_domain_indices()
+ template <typename T>
+ struct has_locally_owned_domain_indices
+ {
+ private:
+ static bool
+ detect(...);
+
+ template <typename U>
+ static decltype(std::declval<U>().locally_owned_domain_indices())
+ detect(const U &);
+
+ public:
+ static const bool value =
+ !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
+ };
+
+ // A helper type-trait that leverage SFINAE to figure out if type T has
+ // void T::locally_owned_range_indices()
+ template <typename T>
+ struct has_locally_owned_range_indices
+ {
+ private:
+ static bool
+ detect(...);
+
+ template <typename U>
+ static decltype(std::declval<U>().locally_owned_range_indices())
+ detect(const U &);
+
+ public:
+ static const bool value =
+ !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
+ };
+
+ // A helper type-trait that leverage SFINAE to figure out if type T has
+ // void T::initialize_dof_vector(VectorType v)
+ template <typename T>
+ struct has_initialize_dof_vector
+ {
+ private:
+ static bool
+ detect(...);
+
+ template <typename U>
+ static decltype(std::declval<U>().initialize_dof_vector(
+ LinearAlgebra::distributed::Vector<double>()))
+ detect(const U &);
+
+ public:
+ static const bool value =
+ !std::is_same<bool, decltype(detect(std::declval<T>()))>::value;
+ };
+
+ // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
+ template <typename MatrixType,
+ typename std::enable_if<
+ has_get_mpi_communicator<MatrixType>::value &&
+ has_locally_owned_domain_indices<MatrixType>::value,
+ MatrixType>::type * = nullptr>
static void
- reinit_range_vector(const Matrix & matrix,
- LinearAlgebra::distributed::Vector<Number> &v,
- bool omit_zeroing_entries)
+ reinit_domain_vector(MatrixType & mat,
+ LinearAlgebra::distributed::Vector<double> &vec,
+ bool /*omit_zeroing_entries*/)
{
- matrix.initialize_dof_vector(v);
- if (!omit_zeroing_entries)
- v = Number();
+ vec.reinit(mat.locally_owned_domain_indices(),
+ mat.get_mpi_communicator());
}
- template <typename Matrix>
+ // Used for MatrixFree and DiagonalMatrix
+ template <
+ typename MatrixType,
+ typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
+ MatrixType>::type * = nullptr>
static void
- reinit_domain_vector(const Matrix & matrix,
- LinearAlgebra::distributed::Vector<Number> &v,
+ reinit_domain_vector(MatrixType & mat,
+ LinearAlgebra::distributed::Vector<double> &vec,
bool omit_zeroing_entries)
{
- matrix.initialize_dof_vector(v);
+ mat.initialize_dof_vector(vec);
+ if (!omit_zeroing_entries)
+ vec = Number();
+ }
+
+ // Used for (Trilinos/PETSc)Wrappers::SparseMatrix
+ template <typename MatrixType,
+ typename std::enable_if<
+ has_get_mpi_communicator<MatrixType>::value &&
+ has_locally_owned_range_indices<MatrixType>::value,
+ MatrixType>::type * = nullptr>
+ static void
+ reinit_range_vector(MatrixType & mat,
+ LinearAlgebra::distributed::Vector<double> &vec,
+ bool /*omit_zeroing_entries*/)
+ {
+ vec.reinit(mat.locally_owned_range_indices(),
+ mat.get_mpi_communicator());
+ }
+
+ // Used for MatrixFree and DiagonalMatrix
+ template <
+ typename MatrixType,
+ typename std::enable_if<has_initialize_dof_vector<MatrixType>::value,
+ MatrixType>::type * = nullptr>
+ static void
+ reinit_range_vector(MatrixType & mat,
+ LinearAlgebra::distributed::Vector<double> &vec,
+ bool omit_zeroing_entries)
+ {
+ mat.initialize_dof_vector(vec);
if (!omit_zeroing_entries)
- v = Number();
+ vec = Number();
}
};
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2016 - 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+// Test that it is possible to use a PackagedOperation created by
+// operator*() of a LinearOperator object for Trilinos matrices and vectors
+
+#include <deal.II/lac/la_parallel_vector.h>
+#include <deal.II/lac/linear_operator_tools.h>
+#include <deal.II/lac/trilinos_block_sparse_matrix.h>
+#include <deal.II/lac/trilinos_sparse_matrix.h>
+
+#include "../tests.h"
+
+
+int
+main(int argc, char *argv[])
+{
+ Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+
+ initlog();
+ deallog << std::setprecision(10);
+
+ typedef LinearAlgebra::distributed::Vector<double> vector_t;
+ typedef TrilinosWrappers::SparseMatrix matrix_t;
+
+ matrix_t a(5U, 4U, 3U);
+ a.compress(VectorOperation::add);
+
+ auto op_a = linear_operator<vector_t>(a);
+ vector_t u, res;
+ op_a.reinit_domain_vector(u, false);
+ res = op_a * u;
+
+ auto op_a_transpose = transpose_operator(op_a);
+ op_a.reinit_range_vector(u, false);
+ res = op_a_transpose * u;
+
+ deallog << "OK" << std::endl;
+
+ return 0;
+}