16 #ifndef dealii__linear_operator_h 17 #define dealii__linear_operator_h 19 #include <deal.II/base/config.h> 20 #include <deal.II/base/exceptions.h> 21 #include <deal.II/lac/vector_memory.h> 23 #ifdef DEAL_II_WITH_CXX11 27 #include <type_traits> 29 DEAL_II_NAMESPACE_OPEN
33 template <
typename Number>
class Vector;
35 template <
typename Range = Vector<
double>,
typename Domain = Range>
38 template <
typename Range = Vector<
double>,
39 typename Domain = Range,
40 typename OperatorExemplar,
45 template <
typename Range = Vector<
double>,
46 typename Domain = Range,
50 template <
typename Range = Vector<
double>,
51 typename Domain = Range>
129 vmult = [](Range &,
const Domain &)
132 "Domain>::vmult called"));
138 "Domain>::vmult_add called"));
141 Tvmult = [](Domain &,
const Range &)
144 "Domain>::Tvmult called"));
150 "Domain>::Tvmult_add called"));
156 "Domain>::reinit_range_vector method called"));
162 "Domain>::reinit_domain_vector method called"));
176 template<
typename Op,
177 typename =
typename std::enable_if<!std::is_base_of<LinearOperator<Range, Domain>, Op>::value>::type>
180 *
this = linear_operator<Range, Domain, Op>(op);
193 template <
typename Op,
194 typename =
typename std::enable_if<!std::is_base_of<LinearOperator<Range, Domain>, Op>::value>::type>
197 *
this = linear_operator<Range, Domain, Op>(op);
205 std::function<void(Range &v, const Domain &u)>
vmult;
211 std::function<void(Range &v, const Domain &u)>
vmult_add;
217 std::function<void(Domain &v, const Range &u)>
Tvmult;
255 *
this = *
this + second_op;
266 *
this = *
this - second_op;
277 *
this = *
this * second_op;
288 *
this = *
this * number;
317 template <
typename Range,
typename Domain>
340 return_op.
vmult = [first_op, second_op](Range &v,
const Domain &u)
342 first_op.
vmult(v, u);
346 return_op.
vmult_add = [first_op, second_op](Range &v,
const Domain &u)
352 return_op.
Tvmult = [first_op, second_op](Domain &v,
const Range &u)
358 return_op.
Tvmult_add = [first_op, second_op](Domain &v,
const Range &u)
378 template <
typename Range,
typename Domain>
385 return -1 * second_op;
394 return first_op + (-1. * second_op);
416 template <
typename Range,
typename Domain>
422 std::is_convertible<typename Range::value_type, typename Domain::value_type>::value,
423 "Range and Domain must have implicitly convertible 'value_type's");
429 else if (number == 0.)
440 return_op.
vmult = [number, op](Range &v,
const Domain &u)
446 return_op.
vmult_add = [number, op](Range &v,
const Domain &u)
453 return_op.
Tvmult = [number, op](Domain &v,
const Range &u)
459 return_op.
Tvmult_add = [number, op](Domain &v,
const Range &u)
486 template <
typename Range,
typename Domain>
489 typename Domain::value_type number)
492 std::is_convertible<typename Range::value_type, typename Domain::value_type>::value,
493 "Range and Domain must have implicitly convertible 'value_type's");
515 template <
typename Range,
typename Intermediate,
typename Domain>
537 return_op.
vmult = [first_op, second_op](Range &v,
const Domain &u)
541 Intermediate *i = vector_memory.
alloc();
543 second_op.
vmult(*i, u);
544 first_op.
vmult(v, *i);
545 vector_memory.
free(i);
548 return_op.
vmult_add = [first_op, second_op](Range &v,
const Domain &u)
552 Intermediate *i = vector_memory.
alloc();
554 second_op.
vmult(*i, u);
556 vector_memory.
free(i);
559 return_op.
Tvmult = [first_op, second_op](Domain &v,
const Range &u)
563 Intermediate *i = vector_memory.
alloc();
567 vector_memory.
free(i);
570 return_op.
Tvmult_add = [first_op, second_op](Domain &v,
const Range &u)
574 Intermediate *i = vector_memory.
alloc();
578 vector_memory.
free(i);
592 template <
typename Range,
typename Domain>
627 template <
typename Solver,
typename Preconditioner>
631 const Preconditioner &preconditioner)
640 return_op.
vmult = [op, &solver, &preconditioner](Vector &v,
const Vector &u)
643 solver.solve(op, v, u, preconditioner);
647 [op, &solver, &preconditioner](Vector &v,
const Vector &u)
651 Vector *v2 = vector_memory.
alloc();
653 solver.solve(op, *v2, u, preconditioner);
655 vector_memory.
free(v2);
658 return_op.
Tvmult = [op, &solver, &preconditioner]( Vector &v,
const 666 [op, &solver, &preconditioner](Vector &v,
const Vector &u)
670 Vector *v2 = vector_memory.
alloc();
674 vector_memory.
free(v2);
699 template <
typename Range>
708 return_op.
vmult = [](Range &v,
const Range &u)
713 return_op.
vmult_add = [](Range &v,
const Range &u)
718 return_op.
Tvmult = [](Range &v,
const Range &u)
723 return_op.
Tvmult_add = [](Range &v,
const Range &u)
741 template <
typename Range,
typename Domain>
749 return_op.vmult = [](Range &v,
const Domain &)
754 return_op.vmult_add = [](Range &,
const Domain &)
757 return_op.Tvmult = [](Domain &v,
const Range &)
762 return_op.Tvmult_add = [](Domain &,
const Range &)
784 template<
typename Vector>
799 template <
typename Matrix>
803 v.
reinit(matrix.m(), omit_zeroing_entries);
817 template <
typename Matrix>
821 v.
reinit(matrix.n(), omit_zeroing_entries);
832 template <
typename Range,
typename Domain,
typename T>
835 template <
typename C>
836 static std::false_type test(...);
838 template <
typename C>
839 static std::true_type test(decltype(&C::vmult_add),
840 decltype(&C::Tvmult_add));
844 #ifndef DEAL_II_ICC_SFINAE_BUG 846 template <
typename C>
847 static std::true_type test(decltype(&C::template vmult_add<Range>),
848 decltype(&C::template Tvmult_add<Range>));
850 template <
typename C>
851 static std::true_type test(decltype(&C::template vmult_add<Range, Domain>),
852 decltype(&C::template Tvmult_add<Domain, Range>));
859 typedef decltype(test<T>(0, 0)) type;
865 template <
typename Function,
typename Range,
typename Domain>
866 void apply_with_intermediate_storage(
Function function, Range &v,
867 const Domain &u,
bool add)
871 Range *i = vector_memory.
alloc();
881 vector_memory.
free(i);
887 template <
typename Range,
typename Domain>
888 class MatrixInterfaceWithoutVmultAdd
891 template <
typename Matrix>
894 op.
vmult = [&matrix](Range &v,
const Domain &u)
899 apply_with_intermediate_storage([&matrix](Range &b,
const Domain &a)
911 op.
vmult_add = [&matrix](Range &v,
const Domain &u)
914 apply_with_intermediate_storage([&matrix](Range &b,
const Domain &a)
921 op.
Tvmult = [&matrix](Domain &v,
const Range &u)
926 apply_with_intermediate_storage([&matrix](Domain &b,
const Range &a)
939 op.
Tvmult_add = [&matrix](Domain &v,
const Range &u)
942 apply_with_intermediate_storage([&matrix](Domain &b,
const Range &a)
953 template <
typename Range,
typename Domain>
954 class MatrixInterfaceWithVmultAdd
957 template <
typename Matrix>
962 MatrixInterfaceWithoutVmultAdd<Range, Domain>().
operator()(op, matrix);
966 op.
vmult_add = [&matrix](Range &v,
const Domain &u)
970 apply_with_intermediate_storage([&matrix](Range &b,
const Domain &a)
978 matrix.vmult_add(v,u);
982 op.
Tvmult_add = [&matrix](Domain &v,
const Range &u)
986 apply_with_intermediate_storage([&matrix](Domain &b,
const Range &a)
994 matrix.Tvmult_add(v,u);
1060 template <
typename Range,
typename Domain,
typename Matrix>
1064 return linear_operator<Range, Domain, Matrix, Matrix>(matrix, matrix);
1083 template <
typename Range,
1085 typename OperatorExemplar,
1107 typename std::conditional<
1108 has_vmult_add<Range, Domain, Matrix>::type::value,
1109 MatrixInterfaceWithVmultAdd<Range, Domain>,
1110 MatrixInterfaceWithoutVmultAdd<Range, Domain>>::type().
1111 operator()(return_op, matrix);
1118 DEAL_II_NAMESPACE_CLOSE
1120 #endif // DEAL_II_WITH_CXX11
LinearOperator< Range, Domain > operator+(const LinearOperator< Range, Domain > &first_op, const LinearOperator< Range, Domain > &second_op)
LinearOperator< Range, Domain > operator-(const LinearOperator< Range, Domain > &first_op, const LinearOperator< Range, Domain > &second_op)
LinearOperator< Range, Domain > linear_operator(const Matrix &matrix)
::ExceptionBase & ExcMessage(std::string arg1)
LinearOperator< Range, Domain > & operator-=(const LinearOperator< Range, Domain > &second_op)
LinearOperator(const Op &op)
std::function< void(Range &v, bool omit_zeroing_entries)> reinit_range_vector
static void reinit_domain_vector(const Matrix &matrix, Vector &v, bool omit_zeroing_entries)
LinearOperator< Range, Domain > & operator+=(const LinearOperator< Range, Domain > &second_op)
std::function< void(Domain &v, const Range &u)> Tvmult_add
LinearOperator< Range, Domain > null_operator(const LinearOperator< Range, Domain > &op)
virtual VectorType * alloc()
#define Assert(cond, exc)
static bool equal(const T *p1, const T *p2)
LinearOperator< Range, Domain > operator*(typename Range::value_type number, const LinearOperator< Range, Domain > &op)
LinearOperator< Range, Domain > operator*(const LinearOperator< Range, Intermediate > &first_op, const LinearOperator< Intermediate, Domain > &second_op)
virtual void free(const VectorType *const)
LinearOperator< Range, Domain > & operator=(const LinearOperator< Range, Domain > &)=default
LinearOperator< typename Solver::vector_type, typename Solver::vector_type > inverse_operator(const LinearOperator< typename Solver::vector_type, typename Solver::vector_type > &op, Solver &solver, const Preconditioner &preconditioner)
std::function< void(Domain &v, bool omit_zeroing_entries)> reinit_domain_vector
LinearOperator< Range, Range > identity_operator(const std::function< void(Range &, bool)> &reinit_vector)
static void reinit_range_vector(const Matrix &matrix, Vector &v, bool omit_zeroing_entries)
LinearOperator< Range, Domain > operator*=(typename Domain::value_type number)
LinearOperator< Range, Domain > & operator*=(const LinearOperator< Domain, Domain > &second_op)
LinearOperator< Range, Domain > operator*(const LinearOperator< Range, Domain > &op, typename Domain::value_type number)
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
std::function< void(Range &v, const Domain &u)> vmult
std::function< void(Range &v, const Domain &u)> vmult_add
LinearOperator< Domain, Range > transpose_operator(const LinearOperator< Range, Domain > &op)
std::function< void(Domain &v, const Range &u)> Tvmult
LinearOperator< Range, Domain > linear_operator(const OperatorExemplar &operator_exemplar, const Matrix &matrix)
LinearOperator< Range, Domain > & operator=(const Op &op)