Reference documentation for deal.II version 9.1.0-pre
linear_operator.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2014 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_linear_operator_h
17 #define dealii_linear_operator_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/exceptions.h>
22 
23 #include <deal.II/lac/vector_memory.h>
24 
25 #include <array>
26 #include <functional>
27 #include <type_traits>
28 
29 DEAL_II_NAMESPACE_OPEN
30 
31 // Forward declarations:
32 
33 namespace internal
34 {
35  namespace LinearOperatorImplementation
36  {
37  class EmptyPayload;
38  }
39 } // namespace internal
40 
41 template <typename Number>
42 class Vector;
43 
44 template <typename Range = Vector<double>,
45  typename Domain = Range,
46  typename Payload =
47  internal::LinearOperatorImplementation::EmptyPayload>
49 
50 template <
51  typename Range = Vector<double>,
52  typename Domain = Range,
54  typename OperatorExemplar,
55  typename Matrix>
57 linear_operator(const OperatorExemplar &, const Matrix &);
58 
59 template <
60  typename Range = Vector<double>,
61  typename Domain = Range,
63  typename Matrix>
65 linear_operator(const Matrix &);
66 
67 template <
68  typename Range = Vector<double>,
69  typename Domain = Range,
73 
74 
158 template <typename Range, typename Domain, typename Payload>
159 class LinearOperator : public Payload
160 {
161 public:
170  LinearOperator(const Payload &payload = Payload())
171  : Payload(payload)
172  , is_null_operator(false)
173  {
174  vmult = [](Range &, const Domain &) {
175  Assert(false,
176  ExcMessage("Uninitialized LinearOperator<Range, "
177  "Domain>::vmult called"));
178  };
179 
180  vmult_add = [](Range &, const Domain &) {
181  Assert(false,
182  ExcMessage("Uninitialized LinearOperator<Range, "
183  "Domain>::vmult_add called"));
184  };
185 
186  Tvmult = [](Domain &, const Range &) {
187  Assert(false,
188  ExcMessage("Uninitialized LinearOperator<Range, "
189  "Domain>::Tvmult called"));
190  };
191 
192  Tvmult_add = [](Domain &, const Range &) {
193  Assert(false,
194  ExcMessage("Uninitialized LinearOperator<Range, "
195  "Domain>::Tvmult_add called"));
196  };
197 
198  reinit_range_vector = [](Range &, bool) {
199  Assert(false,
200  ExcMessage("Uninitialized LinearOperator<Range, "
201  "Domain>::reinit_range_vector method called"));
202  };
203 
204  reinit_domain_vector = [](Domain &, bool) {
205  Assert(false,
206  ExcMessage("Uninitialized LinearOperator<Range, "
207  "Domain>::reinit_domain_vector method called"));
208  };
209  }
210 
215 
221  template <typename Op,
222  typename = typename std::enable_if<
223  !std::is_base_of<LinearOperator<Range, Domain, Payload>,
224  Op>::value>::type>
225  LinearOperator(const Op &op)
226  {
227  *this = linear_operator<Range, Domain, Payload, Op>(op);
228  }
229 
234  operator=(const LinearOperator<Range, Domain, Payload> &) = default;
235 
240  template <typename Op,
241  typename = typename std::enable_if<
242  !std::is_base_of<LinearOperator<Range, Domain, Payload>,
243  Op>::value>::type>
245  operator=(const Op &op)
246  {
247  *this = linear_operator<Range, Domain, Payload, Op>(op);
248  return *this;
249  }
250 
255  std::function<void(Range &v, const Domain &u)> vmult;
256 
261  std::function<void(Range &v, const Domain &u)> vmult_add;
262 
267  std::function<void(Domain &v, const Range &u)> Tvmult;
268 
273  std::function<void(Domain &v, const Range &u)> Tvmult_add;
274 
282  std::function<void(Range &v, bool omit_zeroing_entries)> reinit_range_vector;
283 
291  std::function<void(Domain &v, bool omit_zeroing_entries)>
293 
298 
305  {
306  *this = *this + second_op;
307  return *this;
308  }
309 
316  {
317  *this = *this - second_op;
318  return *this;
319  }
320 
327  {
328  *this = *this * second_op;
329  return *this;
330  }
331 
337  operator*=(typename Domain::value_type number)
338  {
339  *this = *this * number;
340  return *this;
341  }
342 
349 
351 };
352 
353 
358 
368 template <typename Range, typename Domain, typename Payload>
372 {
373  if (first_op.is_null_operator)
374  {
375  return second_op;
376  }
377  else if (second_op.is_null_operator)
378  {
379  return first_op;
380  }
381  else
382  {
384  static_cast<const Payload &>(first_op) +
385  static_cast<const Payload &>(second_op));
386 
387  return_op.reinit_range_vector = first_op.reinit_range_vector;
388  return_op.reinit_domain_vector = first_op.reinit_domain_vector;
389 
390  // ensure to have valid computation objects by catching first_op and
391  // second_op by value
392 
393  return_op.vmult = [first_op, second_op](Range &v, const Domain &u) {
394  first_op.vmult(v, u);
395  second_op.vmult_add(v, u);
396  };
397 
398  return_op.vmult_add = [first_op, second_op](Range &v, const Domain &u) {
399  first_op.vmult_add(v, u);
400  second_op.vmult_add(v, u);
401  };
402 
403  return_op.Tvmult = [first_op, second_op](Domain &v, const Range &u) {
404  second_op.Tvmult(v, u);
405  first_op.Tvmult_add(v, u);
406  };
407 
408  return_op.Tvmult_add = [first_op, second_op](Domain &v, const Range &u) {
409  second_op.Tvmult_add(v, u);
410  first_op.Tvmult_add(v, u);
411  };
412 
413  return return_op;
414  }
415 }
416 
417 
427 template <typename Range, typename Domain, typename Payload>
431 {
432  if (first_op.is_null_operator)
433  {
434  return -1. * second_op;
435  }
436  else if (second_op.is_null_operator)
437  {
438  return first_op;
439  }
440  else
441  {
442  // implement with addition and scalar multiplication
443  return first_op + (-1. * second_op);
444  }
445 }
446 
447 
465 template <typename Range, typename Domain, typename Payload>
467 operator*(typename Range::value_type number,
469 {
470  static_assert(
471  std::is_convertible<typename Range::value_type,
472  typename Domain::value_type>::value,
473  "Range and Domain must have implicitly convertible 'value_type's");
474 
475  if (op.is_null_operator)
476  {
477  return op;
478  }
479  else if (number == 0.)
480  {
481  return null_operator(op);
482  }
483  else
484  {
486 
487  // ensure to have valid computation objects by catching number and op by
488  // value
489 
490  return_op.vmult = [number, op](Range &v, const Domain &u) {
491  op.vmult(v, u);
492  v *= number;
493  };
494 
495  return_op.vmult_add = [number, op](Range &v, const Domain &u) {
496  v /= number;
497  op.vmult_add(v, u);
498  v *= number;
499  };
500 
501  return_op.Tvmult = [number, op](Domain &v, const Range &u) {
502  op.Tvmult(v, u);
503  v *= number;
504  };
505 
506  return_op.Tvmult_add = [number, op](Domain &v, const Range &u) {
507  v /= number;
508  op.Tvmult_add(v, u);
509  v *= number;
510  };
511 
512  return return_op;
513  }
514 }
515 
516 
532 template <typename Range, typename Domain, typename Payload>
535  typename Domain::value_type number)
536 {
537  static_assert(
538  std::is_convertible<typename Range::value_type,
539  typename Domain::value_type>::value,
540  "Range and Domain must have implicitly convertible 'value_type's");
541 
542  return number * op;
543 }
544 
546 
547 
552 
562 template <typename Range,
563  typename Intermediate,
564  typename Domain,
565  typename Payload>
569 {
570  if (first_op.is_null_operator || second_op.is_null_operator)
571  {
573  return_op.reinit_domain_vector = second_op.reinit_domain_vector;
574  return_op.reinit_range_vector = first_op.reinit_range_vector;
575  return null_operator(return_op);
576  }
577  else
578  {
580  static_cast<const Payload &>(first_op) *
581  static_cast<const Payload &>(second_op));
582 
583  return_op.reinit_domain_vector = second_op.reinit_domain_vector;
584  return_op.reinit_range_vector = first_op.reinit_range_vector;
585 
586  // ensure to have valid computation objects by catching first_op and
587  // second_op by value
588 
589  return_op.vmult = [first_op, second_op](Range &v, const Domain &u) {
590  GrowingVectorMemory<Intermediate> vector_memory;
591 
592  typename VectorMemory<Intermediate>::Pointer i(vector_memory);
593  second_op.reinit_range_vector(*i, /*bool omit_zeroing_entries =*/true);
594  second_op.vmult(*i, u);
595  first_op.vmult(v, *i);
596  };
597 
598  return_op.vmult_add = [first_op, second_op](Range &v, const Domain &u) {
599  GrowingVectorMemory<Intermediate> vector_memory;
600 
601  typename VectorMemory<Intermediate>::Pointer i(vector_memory);
602  second_op.reinit_range_vector(*i, /*bool omit_zeroing_entries =*/true);
603  second_op.vmult(*i, u);
604  first_op.vmult_add(v, *i);
605  };
606 
607  return_op.Tvmult = [first_op, second_op](Domain &v, const Range &u) {
608  GrowingVectorMemory<Intermediate> vector_memory;
609 
610  typename VectorMemory<Intermediate>::Pointer i(vector_memory);
611  first_op.reinit_domain_vector(*i, /*bool omit_zeroing_entries =*/true);
612  first_op.Tvmult(*i, u);
613  second_op.Tvmult(v, *i);
614  };
615 
616  return_op.Tvmult_add = [first_op, second_op](Domain &v, const Range &u) {
617  GrowingVectorMemory<Intermediate> vector_memory;
618 
619  typename VectorMemory<Intermediate>::Pointer i(vector_memory);
620  first_op.reinit_domain_vector(*i, /*bool omit_zeroing_entries =*/true);
621  first_op.Tvmult(*i, u);
622  second_op.Tvmult_add(v, *i);
623  };
624 
625  return return_op;
626  }
627 }
628 
638 template <typename Range, typename Domain, typename Payload>
641 {
642  LinearOperator<Domain, Range, Payload> return_op(op.transpose_payload());
643 
645  return_op.reinit_domain_vector = op.reinit_range_vector;
646 
647  return_op.vmult = op.Tvmult;
648  return_op.vmult_add = op.Tvmult_add;
649  return_op.Tvmult = op.vmult;
650  return_op.Tvmult_add = op.vmult_add;
651 
652  return return_op;
653 }
654 
655 
676 template <typename Payload,
677  typename Solver,
678  typename Preconditioner,
679  typename Range = typename Solver::vector_type,
680  typename Domain = Range>
683  Solver & solver,
684  const Preconditioner & preconditioner)
685 {
687  op.inverse_payload(solver, preconditioner));
688 
690  return_op.reinit_domain_vector = op.reinit_range_vector;
691 
692  return_op.vmult = [op, &solver, &preconditioner](Range &v, const Domain &u) {
693  op.reinit_range_vector(v, /*bool omit_zeroing_entries =*/false);
694  solver.solve(op, v, u, preconditioner);
695  };
696 
697  return_op.vmult_add = [op, &solver, &preconditioner](Range & v,
698  const Domain &u) {
699  GrowingVectorMemory<Range> vector_memory;
700 
701  typename VectorMemory<Range>::Pointer v2(vector_memory);
702  op.reinit_range_vector(*v2, /*bool omit_zeroing_entries =*/false);
703  solver.solve(op, *v2, u, preconditioner);
704  v += *v2;
705  };
706 
707  return_op.Tvmult = [op, &solver, &preconditioner](Range &v, const Domain &u) {
708  op.reinit_range_vector(v, /*bool omit_zeroing_entries =*/false);
709  solver.solve(transpose_operator(op), v, u, preconditioner);
710  };
711 
712  return_op.Tvmult_add = [op, &solver, &preconditioner](Range & v,
713  const Domain &u) {
714  GrowingVectorMemory<Range> vector_memory;
715 
716  typename VectorMemory<Range>::Pointer v2(vector_memory);
717  op.reinit_range_vector(*v2, /*bool omit_zeroing_entries =*/false);
718  solver.solve(transpose_operator(op), *v2, u, preconditioner);
719  v += *v2;
720  };
721 
722  return return_op;
723 }
724 
726 
727 
732 
744 template <
745  typename Range,
748 identity_operator(const std::function<void(Range &, bool)> &reinit_vector)
749 {
750  LinearOperator<Range, Range, Payload> return_op((Payload()));
751 
752  return_op.reinit_range_vector = reinit_vector;
753  return_op.reinit_domain_vector = reinit_vector;
754 
755  return_op.vmult = [](Range &v, const Range &u) { v = u; };
756 
757  return_op.vmult_add = [](Range &v, const Range &u) { v += u; };
758 
759  return_op.Tvmult = [](Range &v, const Range &u) { v = u; };
760 
761  return_op.Tvmult_add = [](Range &v, const Range &u) { v += u; };
762 
763  return return_op;
764 }
765 
766 
779 template <typename Range, typename Domain, typename Payload>
782 {
783  auto return_op = identity_operator<Range, Payload>(op.reinit_range_vector);
784  static_cast<Payload &>(return_op) = op.identity_payload();
785 
786  return return_op;
787 }
788 
789 
799 template <typename Range, typename Domain, typename Payload>
802 {
803  LinearOperator<Range, Domain, Payload> return_op(op.null_payload());
804 
805  return_op.is_null_operator = true;
806 
807  return_op.reinit_range_vector = op.reinit_range_vector;
808  return_op.reinit_domain_vector = op.reinit_domain_vector;
809 
810  return_op.vmult = [](Range &v, const Domain &) { v = 0.; };
811 
812  return_op.vmult_add = [](Range &, const Domain &) {};
813 
814  return_op.Tvmult = [](Domain &v, const Range &) { v = 0.; };
815 
816  return_op.Tvmult_add = [](Domain &, const Range &) {};
817 
818  return return_op;
819 }
820 
821 
834 template <
835  typename Range,
838 mean_value_filter(const std::function<void(Range &, bool)> &reinit_vector)
839 {
840  LinearOperator<Range, Range, Payload> return_op((Payload()));
841 
842  return_op.reinit_range_vector = reinit_vector;
843  return_op.reinit_domain_vector = reinit_vector;
844 
845  return_op.vmult = [](Range &v, const Range &u) {
846  const auto mean = u.mean_value();
847 
848  v = u;
849  v.add(-mean);
850  };
851 
852  return_op.vmult_add = [](Range &v, const Range &u) {
853  const auto mean = u.mean_value();
854 
855  v += u;
856  v.add(-mean);
857  };
858 
859  return_op.Tvmult = return_op.vmult_add;
860  return_op.Tvmult_add = return_op.vmult_add;
861 
862  return return_op;
863 }
864 
865 
878 template <typename Range, typename Domain, typename Payload>
881 {
882  auto return_op = mean_value_filter<Range, Payload>(op.reinit_range_vector);
883  static_cast<Payload &>(return_op) = op.identity_payload();
884 
885  return return_op;
886 }
887 
888 
889 namespace internal
890 {
891  namespace LinearOperatorImplementation
892  {
904  template <typename Vector>
905  class ReinitHelper
906  {
907  public:
919  template <typename Matrix>
920  static void
921  reinit_range_vector(const Matrix &matrix,
922  Vector & v,
923  bool omit_zeroing_entries)
924  {
925  v.reinit(matrix.m(), omit_zeroing_entries);
926  }
927 
939  template <typename Matrix>
940  static void
941  reinit_domain_vector(const Matrix &matrix,
942  Vector & v,
943  bool omit_zeroing_entries)
944  {
945  v.reinit(matrix.n(), omit_zeroing_entries);
946  }
947  };
948 
949 
963  {
964  public:
972  template <typename... Args>
973  EmptyPayload(const Args &...)
974  {}
975 
976 
982  {
983  return *this;
984  }
985 
986 
991  null_payload() const
992  {
993  return *this;
994  }
995 
996 
1000  EmptyPayload
1002  {
1003  return *this;
1004  }
1005 
1006 
1010  template <typename Solver, typename Preconditioner>
1011  EmptyPayload
1012  inverse_payload(Solver &, const Preconditioner &) const
1013  {
1014  return *this;
1015  }
1016  };
1017 
1022  inline EmptyPayload
1023  operator+(const EmptyPayload &, const EmptyPayload &)
1024  {
1025  return EmptyPayload();
1026  }
1027 
1032  inline EmptyPayload operator*(const EmptyPayload &, const EmptyPayload &)
1033  {
1034  return EmptyPayload();
1035  }
1036 
1037 
1038 
1039  // A trait class that determines whether type T provides public
1040  // (templated or non-templated) vmult_add member functions
1041  template <typename Range, typename Domain, typename T>
1042  class has_vmult_add_and_Tvmult_add
1043  {
1044  template <typename C>
1045  static std::false_type
1046  test(...);
1047 
1048  template <typename C>
1049  static auto
1050  test(Range *r, Domain *d)
1051  -> decltype(std::declval<C>().vmult_add(*r, *d),
1052  std::declval<C>().Tvmult_add(*d, *r),
1053  std::true_type());
1054 
1055  public:
1056  // type is std::true_type if Matrix provides vmult_add and Tvmult_add,
1057  // otherwise it is std::false_type
1058 
1059  using type = decltype(test<T>(nullptr, nullptr));
1060  };
1061 
1062 
1063  // A helper function to apply a given vmult, or Tvmult to a vector with
1064  // intermediate storage
1065  template <typename Function, typename Range, typename Domain>
1066  void
1067  apply_with_intermediate_storage(Function function,
1068  Range & v,
1069  const Domain &u,
1070  bool add)
1071  {
1072  GrowingVectorMemory<Range> vector_memory;
1073 
1074  typename VectorMemory<Range>::Pointer i(vector_memory);
1075  i->reinit(v, /*bool omit_zeroing_entries =*/true);
1076 
1077  function(*i, u);
1078 
1079  if (add)
1080  v += *i;
1081  else
1082  v = *i;
1083  }
1084 
1085 
1086  // A helper class to add a reduced matrix interface to a LinearOperator
1087  // (typically provided by Preconditioner classes)
1088  template <typename Range, typename Domain, typename Payload>
1089  class MatrixInterfaceWithoutVmultAdd
1090  {
1091  public:
1092  template <typename Matrix>
1093  void
1095  const Matrix & matrix)
1096  {
1097  op.vmult = [&matrix](Range &v, const Domain &u) {
1098  if (PointerComparison::equal(&v, &u))
1099  {
1100  // If v and u are the same memory location use intermediate
1101  // storage
1102  apply_with_intermediate_storage(
1103  [&matrix](Range &b, const Domain &a) { matrix.vmult(b, a); },
1104  v,
1105  u,
1106  /*bool add =*/false);
1107  }
1108  else
1109  {
1110  matrix.vmult(v, u);
1111  }
1112  };
1113 
1114  op.vmult_add = [&matrix](Range &v, const Domain &u) {
1115  // use intermediate storage to implement vmult_add with vmult
1116  apply_with_intermediate_storage(
1117  [&matrix](Range &b, const Domain &a) { matrix.vmult(b, a); },
1118  v,
1119  u,
1120  /*bool add =*/true);
1121  };
1122 
1123  op.Tvmult = [&matrix](Domain &v, const Range &u) {
1124  if (PointerComparison::equal(&v, &u))
1125  {
1126  // If v and u are the same memory location use intermediate
1127  // storage
1128  apply_with_intermediate_storage(
1129  [&matrix](Domain &b, const Range &a) { matrix.Tvmult(b, a); },
1130  v,
1131  u,
1132  /*bool add =*/false);
1133  }
1134  else
1135  {
1136  matrix.Tvmult(v, u);
1137  }
1138  };
1139 
1140  op.Tvmult_add = [&matrix](Domain &v, const Range &u) {
1141  // use intermediate storage to implement Tvmult_add with Tvmult
1142  apply_with_intermediate_storage(
1143  [&matrix](Domain &b, const Range &a) { matrix.Tvmult(b, a); },
1144  v,
1145  u,
1146  /*bool add =*/true);
1147  };
1148  }
1149  };
1150 
1151 
1152  // A helper class to add the full matrix interface to a LinearOperator
1153  template <typename Range, typename Domain, typename Payload>
1154  class MatrixInterfaceWithVmultAdd
1155  {
1156  public:
1157  template <typename Matrix>
1158  void
1160  const Matrix & matrix)
1161  {
1162  // As above ...
1163 
1164  MatrixInterfaceWithoutVmultAdd<Range, Domain, Payload>().operator()(
1165  op, matrix);
1166 
1167  // ... but add native vmult_add and Tvmult_add variants:
1168 
1169  op.vmult_add = [&matrix](Range &v, const Domain &u) {
1170  if (PointerComparison::equal(&v, &u))
1171  {
1172  apply_with_intermediate_storage(
1173  [&matrix](Range &b, const Domain &a) { matrix.vmult(b, a); },
1174  v,
1175  u,
1176  /*bool add =*/true);
1177  }
1178  else
1179  {
1180  matrix.vmult_add(v, u);
1181  }
1182  };
1183 
1184  op.Tvmult_add = [&matrix](Domain &v, const Range &u) {
1185  if (PointerComparison::equal(&v, &u))
1186  {
1187  apply_with_intermediate_storage(
1188  [&matrix](Domain &b, const Range &a) { matrix.Tvmult(b, a); },
1189  v,
1190  u,
1191  /*bool add =*/true);
1192  }
1193  else
1194  {
1195  matrix.Tvmult_add(v, u);
1196  }
1197  };
1198  }
1199  };
1200  } // namespace LinearOperatorImplementation
1201 } // namespace internal
1202 
1203 
1261 template <typename Range, typename Domain, typename Payload, typename Matrix>
1263 linear_operator(const Matrix &matrix)
1264 {
1265  // implement with the more generic variant below...
1266  return linear_operator<Range, Domain, Payload, Matrix, Matrix>(matrix,
1267  matrix);
1268 }
1269 
1270 
1286 template <typename Range,
1287  typename Domain,
1288  typename Payload,
1289  typename OperatorExemplar,
1290  typename Matrix>
1292 linear_operator(const OperatorExemplar &operator_exemplar, const Matrix &matrix)
1293 {
1295  // Initialize the payload based on the input exemplar matrix
1297  Payload(operator_exemplar, matrix));
1298 
1299  // Always store a reference to matrix and operator_exemplar in the lambda
1300  // functions. This ensures that a modification of the matrix after the
1301  // creation of a LinearOperator wrapper is respected - further a matrix
1302  // or an operator_exemplar cannot usually be copied...
1303 
1304  return_op.reinit_range_vector =
1305  [&operator_exemplar](Range &v, bool omit_zeroing_entries) {
1307  Range>::reinit_range_vector(operator_exemplar, v, omit_zeroing_entries);
1308  };
1309 
1310  return_op.reinit_domain_vector = [&operator_exemplar](
1311  Domain &v, bool omit_zeroing_entries) {
1313  Domain>::reinit_domain_vector(operator_exemplar, v, omit_zeroing_entries);
1314  };
1315 
1316  typename std::conditional<
1317  has_vmult_add_and_Tvmult_add<Range, Domain, Matrix>::type::value,
1318  MatrixInterfaceWithVmultAdd<Range, Domain, Payload>,
1319  MatrixInterfaceWithoutVmultAdd<Range, Domain, Payload>>::type()
1320  .
1321  operator()(return_op, matrix);
1322 
1323  return return_op;
1324 }
1325 
1326 
1327 
1345 template <typename Range, typename Domain, typename Payload, typename Matrix>
1348  const Matrix & matrix)
1349 {
1351  // Initialize the payload based on the LinearOperator exemplar
1352  auto return_op = operator_exemplar;
1353 
1354  typename std::conditional<
1355  has_vmult_add_and_Tvmult_add<Range, Domain, Matrix>::type::value,
1356  MatrixInterfaceWithVmultAdd<Range, Domain, Payload>,
1357  MatrixInterfaceWithoutVmultAdd<Range, Domain, Payload>>::type()
1358  .
1359  operator()(return_op, matrix);
1360 
1361  return return_op;
1362 }
1363 
1364 
1366 
1367 
1368 DEAL_II_NAMESPACE_CLOSE
1369 
1370 #endif
VectorType vector_type
Definition: solver.h:334
EmptyPayload inverse_payload(Solver &, const Preconditioner &) const
LinearOperator< Range, Range, Payload > mean_value_filter(const std::function< void(Range &, bool)> &reinit_vector)
std::function< void(Range &v, bool omit_zeroing_entries)> reinit_range_vector
std::function< void(Domain &v, const Range &u)> Tvmult_add
std::function< void(Domain &v, const Range &u)> Tvmult
LinearOperator< Range, Domain, Payload > operator*=(typename Domain::value_type number)
LinearOperator< Range, Domain, Payload > operator+(const LinearOperator< Range, Domain, Payload > &first_op, const LinearOperator< Range, Domain, Payload > &second_op)
LinearOperator< Range, Domain, Payload > & operator*=(const LinearOperator< Domain, Domain, Payload > &second_op)
static void reinit_range_vector(const Matrix &matrix, Vector &v, bool omit_zeroing_entries)
LinearOperator< Domain, Range, Payload > transpose_operator(const LinearOperator< Range, Domain, Payload > &op)
LinearOperator< Range, Domain, Payload > null_operator(const LinearOperator< Range, Domain, Payload > &)
static void reinit_domain_vector(const Matrix &matrix, Vector &v, bool omit_zeroing_entries)
static::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:1227
std::function< void(Range &v, const Domain &u)> vmult
LinearOperator< Range, Domain, Payload > & operator=(const Op &op)
LinearOperator< Range, Domain, Payload > & operator-=(const LinearOperator< Range, Domain, Payload > &second_op)
std::function< void(Domain &v, bool omit_zeroing_entries)> reinit_domain_vector
LinearOperator< Range, Domain, Payload > operator*(typename Range::value_type number, const LinearOperator< Range, Domain, Payload > &op)
LinearOperator< Range, Range, Payload > identity_operator(const std::function< void(Range &, bool)> &reinit_vector)
LinearOperator< Range, Domain, Payload > operator-(const LinearOperator< Range, Domain, Payload > &first_op, const LinearOperator< Range, Domain, Payload > &second_op)
Definition: solver.h:328
std::function< void(Range &v, const Domain &u)> vmult_add
LinearOperator< Domain, Range, Payload > inverse_operator(const LinearOperator< Range, Domain, Payload > &op, Solver &solver, const Preconditioner &preconditioner)
LinearOperator< Range, Domain, Payload > & operator+=(const LinearOperator< Range, Domain, Payload > &second_op)
LinearOperator(const Payload &payload=Payload())
LinearOperator< Range, Domain, Payload > linear_operator(const OperatorExemplar &, const Matrix &)
static bool equal(const T *p1, const T *p2)
LinearOperator(const Op &op)