namespace
{
- // A trait class that determines whether type T provides public
- // (templated or non-templated) vmult and Tvmult member functions
-
- template <typename Range, typename Domain, typename T>
- class has_vmult
- {
- template <typename C>
- static std::false_type test(...);
-
- template <typename C>
- static std::true_type test(decltype(&C::vmult),
- decltype(&C::Tvmult));
-
- template <typename C>
- static std::true_type test(decltype(&C::template vmult<Range>),
- decltype(&C::template Tvmult<Range>));
-
- template <typename C>
- static std::true_type test(decltype(&C::template vmult<Range, Domain>),
- decltype(&C::template Tvmult<Domain, Range>));
-
- public:
- // type is std::true_type if Matrix provides vmult and Tvmult,
- // otherwise it is std::false_type
-
- typedef decltype(test<T>(0, 0)) type;
- };
-
// A trait class that determines whether type T provides public
// (templated or non-templated) vmult_add and Tvmult_add member functions
return return_op;
}
-
-/**
- * @relates LinearOperator
- *
- * Create a LinearOperator by multiplying two matrix objects that are
- * compatible with Vector<double>. 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 <typename Matrix1,
- typename Matrix2,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Vector<double> >, Matrix1>::value>::type,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Vector<double> >, Matrix2>::value>::type,
- typename = typename std::enable_if<has_vmult<Vector<double>, Vector<double>, Matrix1>::type::value>::type,
- typename = typename std::enable_if<has_vmult<Vector<double>, Vector<double>, Matrix2>::type::value>::type>
-LinearOperator<Vector<double>, Vector<double> >
-operator*(const Matrix1 &first_matrix,
- const Matrix2 &second_matrix)
-{
- return linear_operator<Vector<double>>(first_matrix) *
- linear_operator<Vector<double>>(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<double>. 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 <typename Range,
- typename Intermediate,
- typename Matrix,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Vector<double> >, Matrix>::value>::type,
- typename = typename std::enable_if<has_vmult<Vector<double>, Vector<double>, Matrix>::type::value>::type>
-LinearOperator<Range, Vector<double> >
-operator*(const LinearOperator<Range, Intermediate> &op,
- const Matrix &matrix)
-{
- return op * linear_operator<Intermediate, Vector<double>>(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<double>. 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 <typename Intermediate,
- typename Domain,
- typename Matrix,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Vector<double> >, Matrix>::value>::type,
- typename = typename std::enable_if<has_vmult<Vector<double>, Vector<double>, Matrix>::type::value>::type>
-LinearOperator<Vector<double>, Domain>
-operator*(const Matrix &matrix,
- const LinearOperator<Intermediate, Domain> &op)
-{
- return linear_operator<Vector<double>, Intermediate>(matrix) * op;
-}
-
//@}
return return_comp;
}
-
-/**
- * @relates PackagedOperation
- *
- * Create a PackagedOperation object from a reference to a matrix @p m and
- * a reference to a vector @p u of the Domain space. The object stores the
- * PackagedOperation $\text{m} \,u$ (in matrix notation). If a different
- * result type than Domain is desired, the matrix should be
- * explicitly wrapper with linear_operator instead.
- *
- * <code>return</code> (<code>return_add</code>) are implemented with
- * <code>vmult(_1,u)</code> (<code>vmult_add(_1,u)</code>).
- *
- * The PackagedOperation object that is created stores references to @p u
- * and @p m. Thus, both must remain valid references for the whole lifetime
- * of the PackagedOperation object. All changes made on @p u or @p m after
- * the creation of the PackagedOperation object are reflected by the
- * operator object.
- *
- * @ingroup LAOperators
- */
-template <typename Domain,
- typename Matrix,
- typename = typename std::enable_if<has_vector_interface<Domain>::type::value>::type,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Domain, Domain>, Matrix>::value>::type,
- typename = typename std::enable_if<has_vmult<Domain, Domain, Matrix>::type::value>::type>
-PackagedOperation<Domain>
-operator*(const Matrix &m,
- const Domain &u)
-{
- return linear_operator<Domain, Domain>(m) * u;
-}
-
-
-/**
- * @relates PackagedOperation
- *
- * Same as above, taking a packaged operation instead of a vector.
- *
- * @ingroup LAOperators
- */
-template <typename Domain,
- typename Matrix,
- typename = typename std::enable_if<has_vector_interface<Domain>::type::value>::type,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Domain, Domain>, Matrix>::value>::type,
- typename = typename std::enable_if<has_vmult<Domain, Domain, Matrix>::type::value>::type>
-PackagedOperation<Domain>
-operator*(const Matrix &m,
- const PackagedOperation<Domain> &u)
-{
- return linear_operator<Domain, Domain>(m) * u;
-}
-
-
-/**
- * @relates PackagedOperation
- *
- * Create a PackagedOperation object from a reference to a matrix @p m and
- * a reference to a vector @p u of the Range space. The object stores the
- * PackagedOperation $\text{m}^T \,u$ (in matrix notation). If a different
- * result type than Range is desired, the matrix should be
- * explicitly wrapper with linear_operator instead.
- *
- * <code>return</code> (<code>return_add</code>) are implemented with
- * <code>Tvmult(_1,u)</code> (<code>Tvmult_add(_1,u)</code>).
- *
- * The PackagedOperation object that is created stores references to @p u
- * and @p m. Thus, both must remain valid references for the whole lifetime
- * of the PackagedOperation object. All changes made on @p u or @p m after
- * the creation of the PackagedOperation object are reflected by the
- * operator object.
- *
- * @ingroup LAOperators
- */
-template <typename Range,
- typename Matrix,
- typename = typename std::enable_if<has_vector_interface<Range>::type::value>::type,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Range, Range>, Matrix>::value>::type,
- typename = typename std::enable_if<has_vmult<Range, Range, Matrix>::type::value>::type>
-PackagedOperation<Range>
-operator*(const Range &u,
- const Matrix &m)
-{
- return u * linear_operator<Range, Range>(m);
-}
-
-
-/**
- * @relates PackagedOperation
- *
- * Same as above, taking a packaged operation instead of a vector.
- *
- * @ingroup LAOperators
- */
-template <typename Range,
- typename Matrix,
- typename = typename std::enable_if<has_vector_interface<Range>::type::value>::type,
- typename = typename std::enable_if<! std::is_convertible<LinearOperator<Range, Range>, Matrix>::value>::type,
- typename = typename std::enable_if<has_vmult<Range, Range, Matrix>::type::value>::type>
-PackagedOperation<Range>
-operator*(const PackagedOperation<Range> &u,
- const Matrix &m)
-{
- return u * linear_operator<Range, Range>(m);
-}
-
//@}
DEAL_II_NAMESPACE_CLOSE