From: Matthias Maier Date: Fri, 1 May 2015 11:37:15 +0000 (+0200) Subject: Allow multiplication with matrices and creation by multiplication of matrices X-Git-Tag: v8.3.0-rc1~179^2~13 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ad2f222bfe5880403794f5dcc59bce3232d949f5;p=dealii.git Allow multiplication with matrices and creation by multiplication of matrices --- diff --git a/include/deal.II/lac/linear_operator.h b/include/deal.II/lac/linear_operator.h index 71915eb777..04776a6c0f 100644 --- a/include/deal.II/lac/linear_operator.h +++ b/include/deal.II/lac/linear_operator.h @@ -722,6 +722,34 @@ namespace internal namespace { + // A trait class that determines whether type T provides public + // (templated or non-templated) vmult and Tvmult member functions + + template + class has_vmult + { + template + static std::false_type test(...); + + template + static std::true_type test(decltype(&C::vmult), + decltype(&C::Tvmult)); + + template + static std::true_type test(decltype(&C::template vmult), + decltype(&C::template Tvmult)); + + template + static std::true_type test(decltype(&C::template vmult), + decltype(&C::template Tvmult)); + + public: + // type is std::true_type if Matrix provides vmult and Tvmult, + // otherwise it is std::false_type + + typedef decltype(test(0, 0)) type; + }; + // A trait class that determines whether type T provides public // (templated or non-templated) vmult_add and Tvmult_add member functions @@ -946,6 +974,94 @@ linear_operator(const OperatorExemplar &operator_exemplar, const Matrix &matrix) return return_op; } + +/** + * @relates LinearOperator + * + * Create a LinearOperator by multiplying two matrix objects that are + * compatible with Vector. If other vector types are desired, + * explicitly wrap the matrices with linear_operator. + * + * The LinearOperator object that is created stores references to + * @p first_matrix and @p second_matrix. Thus, both objects must remain a valid + * reference for the whole lifetime of the LinearOperator object, see the + * documentation of linear_operator. + * + * @ingroup LAOperators + */ +template >, Matrix1>::value>::type, + typename = typename std::enable_if>, Matrix2>::value>::type, + typename = typename std::enable_if, Vector, Matrix1>::type::value>::type, + typename = typename std::enable_if, Vector, Matrix2>::type::value>::type + > +LinearOperator, Vector> +operator*(const Matrix1 &first_matrix, + const Matrix2 &second_matrix) +{ + return linear_operator>(first_matrix) * + linear_operator>(second_matrix); +} + + +/** + * @relates LinearOperator + * + * Create a LinearOperator by multiplying a LinearOperator with a + * compatible matrix. The Domain type of the resulting LinearOperator is + * set to Vector. If other vector types are + * desired, explicitly wrap the matrix with linear_operator. + * + * The LinearOperator object that is created stores references to + * @p matrix. Thus, both @p matrix must remain a valid reference for the whole + * lifetime of the LinearOperator object, see the documentation of + * linear_operator. + * + * @ingroup LAOperators + */ +template >, Matrix>::value>::type, + typename = typename std::enable_if, Vector, Matrix>::type::value>::type + > +LinearOperator> +operator*(const LinearOperator &op, + const Matrix &matrix) +{ + return op * linear_operator>(matrix); +} + + +/** + * @relates LinearOperator + * + * Create a LinearOperator by multiplying a compatible matrix with a + * LinearOperator. The Range type of the resulting LinearOperator is set to + * Vector. If other vector types are desired, explicitly wrap the + * matrix with linear_operator. + * + * The LinearOperator object that is created stores references to + * @p matrix. Thus, both @p matrix must remain a valid reference for the whole + * lifetime of the LinearOperator object, see the documentation of + * linear_operator. + * + * @ingroup LAOperators + */ +template >, Matrix>::value>::type, + typename = typename std::enable_if, Vector, Matrix>::type::value>::type + > +LinearOperator, Domain> +operator*(const Matrix &matrix, + const LinearOperator &op) +{ + return linear_operator, Intermediate>(matrix) * op; +} + //@}