Reference documentation for deal.II version 9.1.0-pre
precondition.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 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_precondition_h
17 #define dealii_precondition_h
18 
19 // This file contains simple preconditioners.
20 
21 #include <deal.II/base/config.h>
22 
23 #include <deal.II/base/parallel.h>
24 #include <deal.II/base/smartpointer.h>
25 #include <deal.II/base/template_constraints.h>
26 #include <deal.II/base/thread_management.h>
27 #include <deal.II/base/utilities.h>
28 
29 #include <deal.II/lac/diagonal_matrix.h>
30 #include <deal.II/lac/solver_cg.h>
31 #include <deal.II/lac/vector_memory.h>
32 
33 DEAL_II_NAMESPACE_OPEN
34 
35 // forward declarations
36 
37 template <typename number>
38 class Vector;
39 template <typename number>
40 class SparseMatrix;
41 namespace LinearAlgebra
42 {
43  namespace distributed
44  {
45  template <typename number>
46  class Vector;
47  }
48 } // namespace LinearAlgebra
49 
50 
51 
78 {
79 public:
84 
90  {
94  AdditionalData() = default;
95  };
96 
101 
106  template <typename MatrixType>
107  void
108  initialize(const MatrixType & matrix,
109  const AdditionalData &additional_data = AdditionalData());
110 
114  template <class VectorType>
115  void
116  vmult(VectorType &, const VectorType &) const;
117 
122  template <class VectorType>
123  void
124  Tvmult(VectorType &, const VectorType &) const;
125 
129  template <class VectorType>
130  void
131  vmult_add(VectorType &, const VectorType &) const;
132 
137  template <class VectorType>
138  void
139  Tvmult_add(VectorType &, const VectorType &) const;
140 
145  void
147  {}
148 
156  size_type
157  m() const;
158 
166  size_type
167  n() const;
168 
169 private:
174 
179 };
180 
181 
182 
197 {
198 public:
203 
208  {
209  public:
214  AdditionalData(const double relaxation = 1.);
215 
219  double relaxation;
220  };
221 
227 
231  void
232  initialize(const AdditionalData &parameters);
233 
239  template <typename MatrixType>
240  void
241  initialize(const MatrixType &matrix, const AdditionalData &parameters);
242 
246  template <class VectorType>
247  void
248  vmult(VectorType &, const VectorType &) const;
249 
254  template <class VectorType>
255  void
256  Tvmult(VectorType &, const VectorType &) const;
260  template <class VectorType>
261  void
262  vmult_add(VectorType &, const VectorType &) const;
263 
268  template <class VectorType>
269  void
270  Tvmult_add(VectorType &, const VectorType &) const;
271 
276  void
278  {}
279 
287  size_type
288  m() const;
289 
297  size_type
298  n() const;
299 
300 private:
304  double relaxation;
305 
310 
315 };
316 
317 
318 
360 template <typename MatrixType = SparseMatrix<double>,
361  class VectorType = Vector<double>>
363 {
364 public:
368  using function_ptr = void (MatrixType::*)(VectorType &,
369  const VectorType &) const;
370 
376  PreconditionUseMatrix(const MatrixType &M, const function_ptr method);
377 
382  void
383  vmult(VectorType &dst, const VectorType &src) const;
384 
385 private:
389  const MatrixType &matrix;
390 
395 };
396 
397 
398 
407 template <typename MatrixType = SparseMatrix<double>>
409 {
410 public:
414  using size_type = typename MatrixType::size_type;
415 
420  {
421  public:
425  AdditionalData(const double relaxation = 1.);
426 
430  double relaxation;
431  };
432 
438  void
439  initialize(const MatrixType & A,
440  const AdditionalData &parameters = AdditionalData());
441 
445  void
446  clear();
447 
452  size_type
453  m() const;
454 
459  size_type
460  n() const;
461 
462 protected:
467 
471  double relaxation;
472 };
473 
474 
475 
504 template <typename MatrixType = SparseMatrix<double>>
505 class PreconditionJacobi : public PreconditionRelaxation<MatrixType>
506 {
507 public:
511  using AdditionalData =
513 
517  template <class VectorType>
518  void
519  vmult(VectorType &, const VectorType &) const;
520 
525  template <class VectorType>
526  void
527  Tvmult(VectorType &, const VectorType &) const;
528 
532  template <class VectorType>
533  void
534  step(VectorType &x, const VectorType &rhs) const;
535 
539  template <class VectorType>
540  void
541  Tstep(VectorType &x, const VectorType &rhs) const;
542 };
543 
544 
592 template <typename MatrixType = SparseMatrix<double>>
593 class PreconditionSOR : public PreconditionRelaxation<MatrixType>
594 {
595 public:
599  using AdditionalData =
601 
605  template <class VectorType>
606  void
607  vmult(VectorType &, const VectorType &) const;
608 
612  template <class VectorType>
613  void
614  Tvmult(VectorType &, const VectorType &) const;
615 
619  template <class VectorType>
620  void
621  step(VectorType &x, const VectorType &rhs) const;
622 
626  template <class VectorType>
627  void
628  Tstep(VectorType &x, const VectorType &rhs) const;
629 };
630 
631 
632 
661 template <typename MatrixType = SparseMatrix<double>>
662 class PreconditionSSOR : public PreconditionRelaxation<MatrixType>
663 {
664 public:
668  using AdditionalData =
670 
674  using size_type = typename MatrixType::size_type;
675 
680 
681 
687  void
688  initialize(const MatrixType & A,
689  const typename BaseClass::AdditionalData &parameters =
690  typename BaseClass::AdditionalData());
691 
695  template <class VectorType>
696  void
697  vmult(VectorType &, const VectorType &) const;
698 
703  template <class VectorType>
704  void
705  Tvmult(VectorType &, const VectorType &) const;
706 
707 
711  template <class VectorType>
712  void
713  step(VectorType &x, const VectorType &rhs) const;
714 
718  template <class VectorType>
719  void
720  Tstep(VectorType &x, const VectorType &rhs) const;
721 
722 private:
727  std::vector<std::size_t> pos_right_of_diagonal;
728 };
729 
730 
763 template <typename MatrixType = SparseMatrix<double>>
764 class PreconditionPSOR : public PreconditionRelaxation<MatrixType>
765 {
766 public:
770  using size_type = typename MatrixType::size_type;
771 
776  {
777  public:
789  const std::vector<size_type> &permutation,
790  const std::vector<size_type> &inverse_permutation,
792  &parameters =
794 
798  const std::vector<size_type> &permutation;
802  const std::vector<size_type> &inverse_permutation;
807  };
808 
820  void
821  initialize(const MatrixType & A,
822  const std::vector<size_type> &permutation,
823  const std::vector<size_type> &inverse_permutation,
825  &parameters =
827 
838  void
839  initialize(const MatrixType &A, const AdditionalData &additional_data);
840 
844  template <class VectorType>
845  void
846  vmult(VectorType &, const VectorType &) const;
847 
851  template <class VectorType>
852  void
853  Tvmult(VectorType &, const VectorType &) const;
854 
855 private:
859  const std::vector<size_type> *permutation;
863  const std::vector<size_type> *inverse_permutation;
864 };
865 
866 
867 
956 template <typename MatrixType = SparseMatrix<double>,
957  typename VectorType = Vector<double>,
958  typename PreconditionerType = DiagonalMatrix<VectorType>>
960 {
961 public:
966 
967  // avoid warning about use of deprecated variables
968 
974  {
978  AdditionalData(const unsigned int degree = 0,
979  const double smoothing_range = 0.,
980  const bool nonzero_starting = false,
981  const unsigned int eig_cg_n_iterations = 8,
982  const double eig_cg_residual = 1e-2,
983  const double max_eigenvalue = 1);
984 
996  unsigned int degree;
997 
1010 
1023  bool nonzero_starting DEAL_II_DEPRECATED;
1024 
1030  unsigned int eig_cg_n_iterations;
1031 
1037 
1044 
1050  VectorType matrix_diagonal_inverse DEAL_II_DEPRECATED;
1051 
1055  std::shared_ptr<PreconditionerType> preconditioner;
1056  };
1057 
1058 
1060 
1072  void
1073  initialize(const MatrixType & matrix,
1074  const AdditionalData &additional_data = AdditionalData());
1075 
1080  void
1081  vmult(VectorType &dst, const VectorType &src) const;
1082 
1087  void
1088  Tvmult(VectorType &dst, const VectorType &src) const;
1089 
1093  void
1094  step(VectorType &dst, const VectorType &src) const;
1095 
1099  void
1100  Tstep(VectorType &dst, const VectorType &src) const;
1101 
1105  void
1106  clear();
1107 
1112  size_type
1113  m() const;
1114 
1119  size_type
1120  n() const;
1121 
1122 private:
1126  SmartPointer<
1127  const MatrixType,
1130 
1134  mutable VectorType update1;
1135 
1139  mutable VectorType update2;
1140 
1144  mutable VectorType update3;
1145 
1151 
1155  double theta;
1156 
1161  double delta;
1162 
1168 
1174 
1179  void
1180  do_chebyshev_loop(VectorType &dst, const VectorType &src) const;
1181 
1188  void
1189  do_transpose_chebyshev_loop(VectorType &dst, const VectorType &src) const;
1190 
1197  void
1198  estimate_eigenvalues(const VectorType &src) const;
1199 };
1200 
1201 
1202 
1204 /* ---------------------------------- Inline functions ------------------- */
1205 
1206 #ifndef DOXYGEN
1207 
1209  : n_rows(0)
1210  , n_columns(0)
1211 {}
1212 
1213 template <typename MatrixType>
1214 inline void
1215 PreconditionIdentity::initialize(const MatrixType &matrix,
1217 {
1218  n_rows = matrix.m();
1219  n_columns = matrix.n();
1220 }
1221 
1222 
1223 template <class VectorType>
1224 inline void
1225 PreconditionIdentity::vmult(VectorType &dst, const VectorType &src) const
1226 {
1227  dst = src;
1228 }
1229 
1230 
1231 
1232 template <class VectorType>
1233 inline void
1234 PreconditionIdentity::Tvmult(VectorType &dst, const VectorType &src) const
1235 {
1236  dst = src;
1237 }
1238 
1239 template <class VectorType>
1240 inline void
1241 PreconditionIdentity::vmult_add(VectorType &dst, const VectorType &src) const
1242 {
1243  dst += src;
1244 }
1245 
1246 
1247 
1248 template <class VectorType>
1249 inline void
1250 PreconditionIdentity::Tvmult_add(VectorType &dst, const VectorType &src) const
1251 {
1252  dst += src;
1253 }
1254 
1257 {
1258  Assert(n_rows != 0, ExcNotInitialized());
1259  return n_rows;
1260 }
1261 
1264 {
1265  Assert(n_columns != 0, ExcNotInitialized());
1266  return n_columns;
1267 }
1268 
1269 //---------------------------------------------------------------------------
1270 
1272  const double relaxation)
1273  : relaxation(relaxation)
1274 {}
1275 
1276 
1278  : relaxation(0)
1279  , n_rows(0)
1280  , n_columns(0)
1281 {
1282  AdditionalData add_data;
1283  relaxation = add_data.relaxation;
1284 }
1285 
1286 
1287 
1288 inline void
1290  const PreconditionRichardson::AdditionalData &parameters)
1291 {
1292  relaxation = parameters.relaxation;
1293 }
1294 
1295 
1296 
1297 template <typename MatrixType>
1298 inline void
1300  const MatrixType & matrix,
1301  const PreconditionRichardson::AdditionalData &parameters)
1302 {
1303  relaxation = parameters.relaxation;
1304  n_rows = matrix.m();
1305  n_columns = matrix.n();
1306 }
1307 
1308 
1309 
1310 template <class VectorType>
1311 inline void
1312 PreconditionRichardson::vmult(VectorType &dst, const VectorType &src) const
1313 {
1314  static_assert(
1315  std::is_same<size_type, typename VectorType::size_type>::value,
1316  "PreconditionRichardson and VectorType must have the same size_type.");
1317 
1318  dst.equ(relaxation, src);
1319 }
1320 
1321 
1322 
1323 template <class VectorType>
1324 inline void
1325 PreconditionRichardson::Tvmult(VectorType &dst, const VectorType &src) const
1326 {
1327  static_assert(
1328  std::is_same<size_type, typename VectorType::size_type>::value,
1329  "PreconditionRichardson and VectorType must have the same size_type.");
1330 
1331  dst.equ(relaxation, src);
1332 }
1333 
1334 template <class VectorType>
1335 inline void
1336 PreconditionRichardson::vmult_add(VectorType &dst, const VectorType &src) const
1337 {
1338  static_assert(
1339  std::is_same<size_type, typename VectorType::size_type>::value,
1340  "PreconditionRichardson and VectorType must have the same size_type.");
1341 
1342  dst.add(relaxation, src);
1343 }
1344 
1345 
1346 
1347 template <class VectorType>
1348 inline void
1349 PreconditionRichardson::Tvmult_add(VectorType &dst, const VectorType &src) const
1350 {
1351  static_assert(
1352  std::is_same<size_type, typename VectorType::size_type>::value,
1353  "PreconditionRichardson and VectorType must have the same size_type.");
1354 
1355  dst.add(relaxation, src);
1356 }
1357 
1360 {
1361  Assert(n_rows != 0, ExcNotInitialized());
1362  return n_rows;
1363 }
1364 
1367 {
1368  Assert(n_columns != 0, ExcNotInitialized());
1369  return n_columns;
1370 }
1371 
1372 //---------------------------------------------------------------------------
1373 
1374 template <typename MatrixType>
1375 inline void
1377  const AdditionalData &parameters)
1378 {
1379  A = &rA;
1380  relaxation = parameters.relaxation;
1381 }
1382 
1383 
1384 template <typename MatrixType>
1385 inline void
1387 {
1388  A = nullptr;
1389 }
1390 
1391 template <typename MatrixType>
1394 {
1395  Assert(A != nullptr, ExcNotInitialized());
1396  return A->m();
1397 }
1398 
1399 template <typename MatrixType>
1402 {
1403  Assert(A != nullptr, ExcNotInitialized());
1404  return A->n();
1405 }
1406 
1407 //---------------------------------------------------------------------------
1408 
1409 template <typename MatrixType>
1410 template <class VectorType>
1411 inline void
1412 PreconditionJacobi<MatrixType>::vmult(VectorType & dst,
1413  const VectorType &src) const
1414 {
1415  static_assert(
1416  std::is_same<typename PreconditionJacobi<MatrixType>::size_type,
1417  typename VectorType::size_type>::value,
1418  "PreconditionJacobi and VectorType must have the same size_type.");
1419 
1420  Assert(this->A != nullptr, ExcNotInitialized());
1421  this->A->precondition_Jacobi(dst, src, this->relaxation);
1422 }
1423 
1424 
1425 
1426 template <typename MatrixType>
1427 template <class VectorType>
1428 inline void
1430  const VectorType &src) const
1431 {
1432  static_assert(
1433  std::is_same<typename PreconditionJacobi<MatrixType>::size_type,
1434  typename VectorType::size_type>::value,
1435  "PreconditionJacobi and VectorType must have the same size_type.");
1436 
1437  Assert(this->A != nullptr, ExcNotInitialized());
1438  this->A->precondition_Jacobi(dst, src, this->relaxation);
1439 }
1440 
1441 
1442 
1443 template <typename MatrixType>
1444 template <class VectorType>
1445 inline void
1446 PreconditionJacobi<MatrixType>::step(VectorType & dst,
1447  const VectorType &src) const
1448 {
1449  static_assert(
1450  std::is_same<typename PreconditionJacobi<MatrixType>::size_type,
1451  typename VectorType::size_type>::value,
1452  "PreconditionJacobi and VectorType must have the same size_type.");
1453 
1454  Assert(this->A != nullptr, ExcNotInitialized());
1455  this->A->Jacobi_step(dst, src, this->relaxation);
1456 }
1457 
1458 
1459 
1460 template <typename MatrixType>
1461 template <class VectorType>
1462 inline void
1463 PreconditionJacobi<MatrixType>::Tstep(VectorType & dst,
1464  const VectorType &src) const
1465 {
1466  static_assert(
1467  std::is_same<typename PreconditionJacobi<MatrixType>::size_type,
1468  typename VectorType::size_type>::value,
1469  "PreconditionJacobi and VectorType must have the same size_type.");
1470 
1471  step(dst, src);
1472 }
1473 
1474 
1475 
1476 //---------------------------------------------------------------------------
1477 
1478 template <typename MatrixType>
1479 template <class VectorType>
1480 inline void
1481 PreconditionSOR<MatrixType>::vmult(VectorType &dst, const VectorType &src) const
1482 {
1483  static_assert(std::is_same<typename PreconditionSOR<MatrixType>::size_type,
1484  typename VectorType::size_type>::value,
1485  "PreconditionSOR and VectorType must have the same size_type.");
1486 
1487  Assert(this->A != nullptr, ExcNotInitialized());
1488  this->A->precondition_SOR(dst, src, this->relaxation);
1489 }
1490 
1491 
1492 
1493 template <typename MatrixType>
1494 template <class VectorType>
1495 inline void
1496 PreconditionSOR<MatrixType>::Tvmult(VectorType & dst,
1497  const VectorType &src) const
1498 {
1499  static_assert(std::is_same<typename PreconditionSOR<MatrixType>::size_type,
1500  typename VectorType::size_type>::value,
1501  "PreconditionSOR and VectorType must have the same size_type.");
1502 
1503  Assert(this->A != nullptr, ExcNotInitialized());
1504  this->A->precondition_TSOR(dst, src, this->relaxation);
1505 }
1506 
1507 
1508 
1509 template <typename MatrixType>
1510 template <class VectorType>
1511 inline void
1512 PreconditionSOR<MatrixType>::step(VectorType &dst, const VectorType &src) const
1513 {
1514  static_assert(std::is_same<typename PreconditionSOR<MatrixType>::size_type,
1515  typename VectorType::size_type>::value,
1516  "PreconditionSOR and VectorType must have the same size_type.");
1517 
1518  Assert(this->A != nullptr, ExcNotInitialized());
1519  this->A->SOR_step(dst, src, this->relaxation);
1520 }
1521 
1522 
1523 
1524 template <typename MatrixType>
1525 template <class VectorType>
1526 inline void
1527 PreconditionSOR<MatrixType>::Tstep(VectorType &dst, const VectorType &src) const
1528 {
1529  static_assert(std::is_same<typename PreconditionSOR<MatrixType>::size_type,
1530  typename VectorType::size_type>::value,
1531  "PreconditionSOR and VectorType must have the same size_type.");
1532 
1533  Assert(this->A != nullptr, ExcNotInitialized());
1534  this->A->TSOR_step(dst, src, this->relaxation);
1535 }
1536 
1537 
1538 
1539 //---------------------------------------------------------------------------
1540 
1541 template <typename MatrixType>
1542 inline void
1544  const MatrixType & rA,
1545  const typename BaseClass::AdditionalData &parameters)
1546 {
1547  this->PreconditionRelaxation<MatrixType>::initialize(rA, parameters);
1548 
1549  // in case we have a SparseMatrix class, we can extract information about
1550  // the diagonal.
1552  dynamic_cast<const SparseMatrix<typename MatrixType::value_type> *>(
1553  &*this->A);
1554 
1555  // calculate the positions first after the diagonal.
1556  if (mat != nullptr)
1557  {
1558  const size_type n = this->A->n();
1559  pos_right_of_diagonal.resize(n, static_cast<std::size_t>(-1));
1560  for (size_type row = 0; row < n; ++row)
1561  {
1562  // find the first element in this line which is on the right of the
1563  // diagonal. we need to precondition with the elements on the left
1564  // only. note: the first entry in each line denotes the diagonal
1565  // element, which we need not check.
1567  it = mat->begin(row) + 1;
1568  for (; it < mat->end(row); ++it)
1569  if (it->column() > row)
1570  break;
1571  pos_right_of_diagonal[row] = it - mat->begin();
1572  }
1573  }
1574 }
1575 
1576 
1577 template <typename MatrixType>
1578 template <class VectorType>
1579 inline void
1580 PreconditionSSOR<MatrixType>::vmult(VectorType & dst,
1581  const VectorType &src) const
1582 {
1583  static_assert(
1584  std::is_same<typename PreconditionSSOR<MatrixType>::size_type,
1585  typename VectorType::size_type>::value,
1586  "PreconditionSSOR and VectorType must have the same size_type.");
1587 
1588  Assert(this->A != nullptr, ExcNotInitialized());
1589  this->A->precondition_SSOR(dst, src, this->relaxation, pos_right_of_diagonal);
1590 }
1591 
1592 
1593 
1594 template <typename MatrixType>
1595 template <class VectorType>
1596 inline void
1597 PreconditionSSOR<MatrixType>::Tvmult(VectorType & dst,
1598  const VectorType &src) const
1599 {
1600  static_assert(
1601  std::is_same<typename PreconditionSSOR<MatrixType>::size_type,
1602  typename VectorType::size_type>::value,
1603  "PreconditionSSOR and VectorType must have the same size_type.");
1604 
1605  Assert(this->A != nullptr, ExcNotInitialized());
1606  this->A->precondition_SSOR(dst, src, this->relaxation, pos_right_of_diagonal);
1607 }
1608 
1609 
1610 
1611 template <typename MatrixType>
1612 template <class VectorType>
1613 inline void
1614 PreconditionSSOR<MatrixType>::step(VectorType &dst, const VectorType &src) const
1615 {
1616  static_assert(
1617  std::is_same<typename PreconditionSSOR<MatrixType>::size_type,
1618  typename VectorType::size_type>::value,
1619  "PreconditionSSOR and VectorType must have the same size_type.");
1620 
1621  Assert(this->A != nullptr, ExcNotInitialized());
1622  this->A->SSOR_step(dst, src, this->relaxation);
1623 }
1624 
1625 
1626 
1627 template <typename MatrixType>
1628 template <class VectorType>
1629 inline void
1630 PreconditionSSOR<MatrixType>::Tstep(VectorType & dst,
1631  const VectorType &src) const
1632 {
1633  static_assert(
1634  std::is_same<typename PreconditionSSOR<MatrixType>::size_type,
1635  typename VectorType::size_type>::value,
1636  "PreconditionSSOR and VectorType must have the same size_type.");
1637 
1638  step(dst, src);
1639 }
1640 
1641 
1642 
1643 //---------------------------------------------------------------------------
1644 
1645 template <typename MatrixType>
1646 inline void
1648  const MatrixType & rA,
1649  const std::vector<size_type> & p,
1650  const std::vector<size_type> & ip,
1651  const typename PreconditionRelaxation<MatrixType>::AdditionalData &parameters)
1652 {
1653  permutation = &p;
1654  inverse_permutation = &ip;
1656 }
1657 
1658 
1659 template <typename MatrixType>
1660 inline void
1661 PreconditionPSOR<MatrixType>::initialize(const MatrixType & A,
1662  const AdditionalData &additional_data)
1663 {
1664  initialize(A,
1665  additional_data.permutation,
1666  additional_data.inverse_permutation,
1667  additional_data.parameters);
1668 }
1669 
1670 
1671 template <typename MatrixType>
1672 template <typename VectorType>
1673 inline void
1674 PreconditionPSOR<MatrixType>::vmult(VectorType & dst,
1675  const VectorType &src) const
1676 {
1677  static_assert(
1678  std::is_same<typename PreconditionPSOR<MatrixType>::size_type,
1679  typename VectorType::size_type>::value,
1680  "PreconditionPSOR and VectorType must have the same size_type.");
1681 
1682  Assert(this->A != nullptr, ExcNotInitialized());
1683  dst = src;
1684  this->A->PSOR(dst, *permutation, *inverse_permutation, this->relaxation);
1685 }
1686 
1687 
1688 
1689 template <typename MatrixType>
1690 template <class VectorType>
1691 inline void
1692 PreconditionPSOR<MatrixType>::Tvmult(VectorType & dst,
1693  const VectorType &src) const
1694 {
1695  static_assert(
1696  std::is_same<typename PreconditionPSOR<MatrixType>::size_type,
1697  typename VectorType::size_type>::value,
1698  "PreconditionPSOR and VectorType must have the same size_type.");
1699 
1700  Assert(this->A != nullptr, ExcNotInitialized());
1701  dst = src;
1702  this->A->TPSOR(dst, *permutation, *inverse_permutation, this->relaxation);
1703 }
1704 
1705 template <typename MatrixType>
1707  const std::vector<size_type> &permutation,
1708  const std::vector<size_type> &inverse_permutation,
1709  const typename PreconditionRelaxation<MatrixType>::AdditionalData &parameters)
1710  : permutation(permutation)
1711  , inverse_permutation(inverse_permutation)
1712  , parameters(parameters)
1713 {}
1714 
1715 
1716 //---------------------------------------------------------------------------
1717 
1718 
1719 template <typename MatrixType, class VectorType>
1721  const MatrixType & M,
1722  const function_ptr method)
1723  : matrix(M)
1724  , precondition(method)
1725 {}
1726 
1727 
1728 
1729 template <typename MatrixType, class VectorType>
1730 void
1732  VectorType & dst,
1733  const VectorType &src) const
1734 {
1735  (matrix.*precondition)(dst, src);
1736 }
1737 
1738 //---------------------------------------------------------------------------
1739 
1740 template <typename MatrixType>
1742  const double relaxation)
1743  : relaxation(relaxation)
1744 {}
1745 
1746 
1747 
1748 //---------------------------------------------------------------------------
1749 
1750 namespace internal
1751 {
1752  namespace PreconditionChebyshevImplementation
1753  {
1754  // for deal.II vectors, perform updates for Chebyshev preconditioner all
1755  // at once to reduce memory transfer. Here, we select between general
1756  // vectors and deal.II vectors where we expand the loop over the (local)
1757  // size of the vector
1758 
1759  // generic part for non-deal.II vectors
1760  template <typename VectorType, typename PreconditionerType>
1761  inline void
1762  vector_updates(const VectorType & src,
1763  const PreconditionerType &preconditioner,
1764  const bool start_zero,
1765  const double factor1,
1766  const double factor2,
1767  VectorType & update1,
1768  VectorType & update2,
1769  VectorType & update3,
1770  VectorType & dst)
1771  {
1772  if (start_zero)
1773  {
1774  update1.equ(factor2, src);
1775  preconditioner.vmult(dst, update1);
1776  update1.equ(-1., dst);
1777  }
1778  else
1779  {
1780  update2 -= src;
1781  preconditioner.vmult(update3, update2);
1782  update2 = update3;
1783  if (factor1 == 0.)
1784  update1.equ(factor2, update2);
1785  else
1786  update1.sadd(factor1, factor2, update2);
1787  dst -= update1;
1788  }
1789  }
1790 
1791  // worker routine for deal.II vectors. Because of vectorization, we need
1792  // to put the loop into an extra structure because the virtual function of
1793  // VectorUpdatesRange prevents the compiler from applying vectorization.
1794  template <typename Number>
1795  struct VectorUpdater
1796  {
1797  VectorUpdater(const Number *src,
1798  const Number *matrix_diagonal_inverse,
1799  const bool start_zero,
1800  const Number factor1,
1801  const Number factor2,
1802  Number * update1,
1803  Number * update2,
1804  Number * dst)
1805  : src(src)
1806  , matrix_diagonal_inverse(matrix_diagonal_inverse)
1807  , do_startup(factor1 == Number())
1808  , start_zero(start_zero)
1809  , factor1(factor1)
1810  , factor2(factor2)
1811  , update1(update1)
1812  , update2(update2)
1813  , dst(dst)
1814  {}
1815 
1816  void
1817  apply_to_subrange(const std::size_t begin, const std::size_t end) const
1818  {
1819  // To circumvent a bug in gcc
1820  // (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63945), we create
1821  // copies of the variables factor1 and factor2 and do not check based on
1822  // factor1.
1823  const Number factor1 = this->factor1;
1824  const Number factor2 = this->factor2;
1825  if (do_startup)
1826  {
1827  if (start_zero)
1828  DEAL_II_OPENMP_SIMD_PRAGMA
1829  for (std::size_t i = begin; i < end; ++i)
1830  {
1831  dst[i] = factor2 * src[i] * matrix_diagonal_inverse[i];
1832  update1[i] = -dst[i];
1833  }
1834  else DEAL_II_OPENMP_SIMD_PRAGMA for (std::size_t i = begin; i < end;
1835  ++i)
1836  {
1837  update1[i] =
1838  ((update2[i] - src[i]) * factor2 * matrix_diagonal_inverse[i]);
1839  dst[i] -= update1[i];
1840  }
1841  }
1842  else
1843  DEAL_II_OPENMP_SIMD_PRAGMA
1844  for (std::size_t i = begin; i < end; ++i)
1845  {
1846  const Number update =
1847  factor1 * update1[i] +
1848  factor2 * ((update2[i] - src[i]) * matrix_diagonal_inverse[i]);
1849  update1[i] = update;
1850  dst[i] -= update;
1851  }
1852  }
1853 
1854  const Number * src;
1855  const Number * matrix_diagonal_inverse;
1856  const bool do_startup;
1857  const bool start_zero;
1858  const Number factor1;
1859  const Number factor2;
1860  mutable Number *update1;
1861  mutable Number *update2;
1862  mutable Number *dst;
1863  };
1864 
1865  template <typename Number>
1866  struct VectorUpdatesRange : public parallel::ParallelForInteger
1867  {
1868  VectorUpdatesRange(const VectorUpdater<Number> &updater,
1869  const std::size_t size)
1870  : updater(updater)
1871  {
1872  if (size < internal::VectorImplementation::minimum_parallel_grain_size)
1873  apply_to_subrange(0, size);
1874  else
1875  apply_parallel(
1876  0,
1877  size,
1878  internal::VectorImplementation::minimum_parallel_grain_size);
1879  }
1880 
1881  ~VectorUpdatesRange() override = default;
1882 
1883  virtual void
1884  apply_to_subrange(const std::size_t begin,
1885  const std::size_t end) const override
1886  {
1887  updater.apply_to_subrange(begin, end);
1888  }
1889 
1890  const VectorUpdater<Number> &updater;
1891  };
1892 
1893  // selection for diagonal matrix around deal.II vector
1894  template <typename Number>
1895  inline void
1896  vector_updates(const ::Vector<Number> & src,
1897  const DiagonalMatrix<::Vector<Number>> &jacobi,
1898  const bool start_zero,
1899  const double factor1,
1900  const double factor2,
1901  ::Vector<Number> & update1,
1902  ::Vector<Number> & update2,
1903  ::Vector<Number> &,
1904  ::Vector<Number> &dst)
1905  {
1906  VectorUpdater<Number> upd(src.begin(),
1907  jacobi.get_vector().begin(),
1908  start_zero,
1909  factor1,
1910  factor2,
1911  update1.begin(),
1912  update2.begin(),
1913  dst.begin());
1914  VectorUpdatesRange<Number>(upd, src.size());
1915  }
1916 
1917  // selection for diagonal matrix around parallel deal.II vector
1918  template <typename Number>
1919  inline void
1920  vector_updates(
1923  const bool start_zero,
1924  const double factor1,
1925  const double factor2,
1930  {
1931  VectorUpdater<Number> upd(src.begin(),
1932  jacobi.get_vector().begin(),
1933  start_zero,
1934  factor1,
1935  factor2,
1936  update1.begin(),
1937  update2.begin(),
1938  dst.begin());
1939  VectorUpdatesRange<Number>(upd, src.local_size());
1940  }
1941 
1942  template <typename MatrixType,
1943  typename VectorType,
1944  typename PreconditionerType>
1945  inline void
1946  initialize_preconditioner(
1947  const MatrixType & matrix,
1948  std::shared_ptr<PreconditionerType> &preconditioner,
1949  VectorType &)
1950  {
1951  (void)matrix;
1952  (void)preconditioner;
1953  AssertThrow(preconditioner.get() != nullptr, ExcNotInitialized());
1954  }
1955 
1956  template <typename MatrixType, typename VectorType>
1957  inline void
1958  initialize_preconditioner(
1959  const MatrixType & matrix,
1960  std::shared_ptr<DiagonalMatrix<VectorType>> &preconditioner,
1961  VectorType & diagonal_inverse)
1962  {
1963  if (preconditioner.get() == nullptr || preconditioner->m() != matrix.m())
1964  {
1965  if (preconditioner.get() == nullptr)
1966  preconditioner = std::make_shared<DiagonalMatrix<VectorType>>();
1967 
1968  Assert(
1969  preconditioner->m() == 0,
1970  ExcMessage(
1971  "Preconditioner appears to be initialized but not sized correctly"));
1972 
1973  // Check if we can initialize from vector that then gets set to zero
1974  // as the matrix will own the memory
1975  preconditioner->reinit(diagonal_inverse);
1976  {
1977  VectorType empty_vector;
1978  diagonal_inverse.reinit(empty_vector);
1979  }
1980 
1981  // This part only works in serial
1982  if (preconditioner->m() != matrix.m())
1983  {
1984  preconditioner->get_vector().reinit(matrix.m());
1985  for (typename VectorType::size_type i = 0; i < matrix.m(); ++i)
1986  preconditioner->get_vector()(i) = 1. / matrix.el(i, i);
1987  }
1988  }
1989  }
1990 
1991  template <typename VectorType>
1992  void
1993  set_initial_guess(VectorType &vector)
1994  {
1995  vector = 1. / std::sqrt(static_cast<double>(vector.size()));
1996  if (vector.locally_owned_elements().is_element(0))
1997  vector(0) = 0.;
1998  }
1999 
2000  template <typename Number>
2001  void
2002  set_initial_guess(::Vector<Number> &vector)
2003  {
2004  // Choose a high-frequency mode consisting of numbers between 0 and 1
2005  // that is cheap to compute (cheaper than random numbers) but avoids
2006  // obviously re-occurring numbers in multi-component systems by choosing
2007  // a period of 11
2008  for (unsigned int i = 0; i < vector.size(); ++i)
2009  vector(i) = i % 11;
2010 
2011  const Number mean_value = vector.mean_value();
2012  vector.add(-mean_value);
2013  }
2014 
2015  template <typename Number>
2016  void
2017  set_initial_guess(
2019  {
2020  // Choose a high-frequency mode consisting of numbers between 0 and 1
2021  // that is cheap to compute (cheaper than random numbers) but avoids
2022  // obviously re-occurring numbers in multi-component systems by choosing
2023  // a period of 11.
2024  // Make initial guess robust with respect to number of processors
2025  // by operating on the global index.
2026  types::global_dof_index first_local_range = 0;
2027  if (!vector.locally_owned_elements().is_empty())
2028  first_local_range = vector.locally_owned_elements().nth_index_in_set(0);
2029  for (unsigned int i = 0; i < vector.local_size(); ++i)
2030  vector.local_element(i) = (i + first_local_range) % 11;
2031 
2032  const Number mean_value = vector.mean_value();
2033  vector.add(-mean_value);
2034  }
2035 
2036  struct EigenvalueTracker
2037  {
2038  public:
2039  void
2040  slot(const std::vector<double> &eigenvalues)
2041  {
2042  values = eigenvalues;
2043  }
2044 
2045  std::vector<double> values;
2046  };
2047  } // namespace PreconditionChebyshevImplementation
2048 } // namespace internal
2049 
2050 
2051 
2052 // avoid warning about deprecated variable nonzero_starting
2053 
2054 template <typename MatrixType, class VectorType, typename PreconditionerType>
2056  AdditionalData::AdditionalData(const unsigned int degree,
2057  const double smoothing_range,
2058  const bool nonzero_starting,
2059  const unsigned int eig_cg_n_iterations,
2060  const double eig_cg_residual,
2061  const double max_eigenvalue)
2062  : degree(degree)
2063  , smoothing_range(smoothing_range)
2064  , nonzero_starting(nonzero_starting)
2065  , eig_cg_n_iterations(eig_cg_n_iterations)
2066  , eig_cg_residual(eig_cg_residual)
2067  , max_eigenvalue(max_eigenvalue)
2068 {}
2069 
2070 
2071 
2072 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2075  : theta(1.)
2076  , delta(1.)
2078 {
2079  static_assert(
2080  std::is_same<size_type, typename VectorType::size_type>::value,
2081  "PreconditionChebyshev and VectorType must have the same size_type.");
2082 }
2083 
2084 
2085 // avoid warning about deprecated variable
2086 // AdditionalData::matrix_diagonal_inverse
2087 
2088 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2089 inline void
2091  const MatrixType & matrix,
2092  const AdditionalData &additional_data)
2093 {
2094  matrix_ptr = &matrix;
2095  data = additional_data;
2096  internal::PreconditionChebyshevImplementation::initialize_preconditioner(
2099 }
2100 
2101 
2102 
2103 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2104 inline void
2106 {
2108  theta = delta = 1.0;
2109  matrix_ptr = nullptr;
2110  {
2111  VectorType empty_vector;
2112  data.matrix_diagonal_inverse.reinit(empty_vector);
2113  update1.reinit(empty_vector);
2114  update2.reinit(empty_vector);
2115  update3.reinit(empty_vector);
2116  }
2117  data.preconditioner.reset();
2118 }
2119 
2120 
2121 
2122 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2123 inline void
2125  estimate_eigenvalues(const VectorType &src) const
2126 {
2128  Assert(data.preconditioner.get() != nullptr, ExcNotInitialized());
2129 
2130  update1.reinit(src);
2131  update2.reinit(src, true);
2132 
2133  // calculate largest eigenvalue using a hand-tuned CG iteration on the
2134  // matrix weighted by its diagonal. we start with a vector that consists of
2135  // ones only, weighted by the length.
2136  double max_eigenvalue, min_eigenvalue;
2137  if (data.eig_cg_n_iterations > 0)
2138  {
2140  ExcMessage(
2141  "Need to set at least two iterations to find eigenvalues."));
2142 
2143  // set a very strict tolerance to force at least two iterations
2144  ReductionControl control(
2146  std::sqrt(
2147  std::numeric_limits<typename VectorType::value_type>::epsilon()),
2148  1e-10,
2149  false,
2150  false);
2151 
2152  internal::PreconditionChebyshevImplementation::EigenvalueTracker
2153  eigenvalue_tracker;
2154  SolverCG<VectorType> solver(control);
2155  solver.connect_eigenvalues_slot(std::bind(
2156  &internal::PreconditionChebyshevImplementation::EigenvalueTracker::slot,
2157  &eigenvalue_tracker,
2158  std::placeholders::_1));
2159 
2160  // set an initial guess which is close to the constant vector but where
2161  // one entry is different to trigger high frequencies
2162  internal::PreconditionChebyshevImplementation::set_initial_guess(update2);
2163 
2164  try
2165  {
2166  solver.solve(*matrix_ptr, update1, update2, *data.preconditioner);
2167  }
2169  {}
2170 
2171  // read the eigenvalues from the attached eigenvalue tracker
2172  if (eigenvalue_tracker.values.empty())
2173  min_eigenvalue = max_eigenvalue = 1;
2174  else
2175  {
2176  min_eigenvalue = eigenvalue_tracker.values.front();
2177 
2178  // include a safety factor since the CG method will in general not
2179  // be converged
2180  max_eigenvalue = 1.2 * eigenvalue_tracker.values.back();
2181  }
2182  }
2183  else
2184  {
2185  max_eigenvalue = data.max_eigenvalue;
2186  min_eigenvalue = data.max_eigenvalue / data.smoothing_range;
2187  }
2188 
2189  const double alpha = (data.smoothing_range > 1. ?
2190  max_eigenvalue / data.smoothing_range :
2191  std::min(0.9 * max_eigenvalue, min_eigenvalue));
2192 
2193  // in case the user set the degree to invalid unsigned int, we have to
2194  // determine the number of necessary iterations from the Chebyshev error
2195  // estimate, given the target tolerance specified by smoothing_range. This
2196  // estimate is based on the error formula given in section 5.1 of
2197  // R. S. Varga, Matrix iterative analysis, 2nd ed., Springer, 2009
2199  {
2200  const double actual_range = max_eigenvalue / alpha;
2201  const double sigma = (1. - std::sqrt(1. / actual_range)) /
2202  (1. + std::sqrt(1. / actual_range));
2203  const double eps = data.smoothing_range;
2204  const_cast<
2206  this)
2207  ->data.degree = 1 + std::log(1. / eps + std::sqrt(1. / eps / eps - 1)) /
2208  std::log(1. / sigma);
2209  }
2210 
2211  const_cast<
2213  ->delta = (max_eigenvalue - alpha) * 0.5;
2214  const_cast<
2216  ->theta = (max_eigenvalue + alpha) * 0.5;
2217 
2218  // We do not need the third auxiliary vector in case we have a
2219  // DiagonalMatrix as preconditioner and use deal.II's own vectors
2220  if (std::is_same<PreconditionerType, DiagonalMatrix<VectorType>>::value ==
2221  false ||
2222  (std::is_same<VectorType,
2224  false &&
2225  std::is_same<VectorType,
2227  typename VectorType::value_type>>::value == false))
2228  update3.reinit(src, true);
2229 
2230  const_cast<
2232  ->eigenvalues_are_initialized = true;
2233 }
2234 
2235 
2236 
2237 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2238 inline void
2240  do_chebyshev_loop(VectorType &dst, const VectorType &src) const
2241 {
2242  // if delta is zero, we do not need to iterate because the updates will be
2243  // zero
2244  if (std::abs(delta) < 1e-40)
2245  return;
2246 
2247  double rhok = delta / theta, sigma = theta / delta;
2248  for (unsigned int k = 0; k < data.degree; ++k)
2249  {
2250  matrix_ptr->vmult(update2, dst);
2251  const double rhokp = 1. / (2. * sigma - rhok);
2252  const double factor1 = rhokp * rhok, factor2 = 2. * rhokp / delta;
2253  rhok = rhokp;
2254  internal::PreconditionChebyshevImplementation::vector_updates(
2255  src,
2257  false,
2258  factor1,
2259  factor2,
2260  update1,
2261  update2,
2262  update3,
2263  dst);
2264  }
2265 }
2266 
2267 
2268 
2269 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2270 inline void
2272  do_transpose_chebyshev_loop(VectorType &dst, const VectorType &src) const
2273 {
2274  double rhok = delta / theta, sigma = theta / delta;
2275  for (unsigned int k = 0; k < data.degree; ++k)
2276  {
2277  matrix_ptr->Tvmult(update2, dst);
2278  const double rhokp = 1. / (2. * sigma - rhok);
2279  const double factor1 = rhokp * rhok, factor2 = 2. * rhokp / delta;
2280  rhok = rhokp;
2281  internal::PreconditionChebyshevImplementation::vector_updates(
2282  src,
2284  false,
2285  factor1,
2286  factor2,
2287  update1,
2288  update2,
2289  update3,
2290  dst);
2291  }
2292 }
2293 
2294 
2295 
2296 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2297 inline void
2299  VectorType & dst,
2300  const VectorType &src) const
2301 {
2303  if (eigenvalues_are_initialized == false)
2304  estimate_eigenvalues(src);
2305 
2306  internal::PreconditionChebyshevImplementation::vector_updates(
2307  src,
2309  true,
2310  0.,
2311  1. / theta,
2312  update1,
2313  update2,
2314  update3,
2315  dst);
2316 
2317  do_chebyshev_loop(dst, src);
2318 }
2319 
2320 
2321 
2322 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2323 inline void
2325  VectorType & dst,
2326  const VectorType &src) const
2327 {
2329  if (eigenvalues_are_initialized == false)
2330  estimate_eigenvalues(src);
2331 
2332  internal::PreconditionChebyshevImplementation::vector_updates(
2333  src,
2335  true,
2336  0.,
2337  1. / theta,
2338  update1,
2339  update2,
2340  update3,
2341  dst);
2342 
2343  do_transpose_chebyshev_loop(dst, src);
2344 }
2345 
2346 
2347 
2348 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2349 inline void
2351  VectorType & dst,
2352  const VectorType &src) const
2353 {
2355  if (eigenvalues_are_initialized == false)
2356  estimate_eigenvalues(src);
2357 
2358  matrix_ptr->vmult(update2, dst);
2359  internal::PreconditionChebyshevImplementation::vector_updates(
2360  src,
2362  false,
2363  0.,
2364  1. / theta,
2365  update1,
2366  update2,
2367  update3,
2368  dst);
2369 
2370  do_chebyshev_loop(dst, src);
2371 }
2372 
2373 
2374 
2375 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2376 inline void
2378  VectorType & dst,
2379  const VectorType &src) const
2380 {
2382  if (eigenvalues_are_initialized == false)
2383  estimate_eigenvalues(src);
2384 
2385  matrix_ptr->Tvmult(update2, dst);
2386  internal::PreconditionChebyshevImplementation::vector_updates(
2387  src,
2389  false,
2390  0.,
2391  1. / theta,
2392  update1,
2393  update2,
2394  update3,
2395  dst);
2396 
2397  do_transpose_chebyshev_loop(dst, src);
2398 }
2399 
2400 
2401 
2402 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2403 inline typename PreconditionChebyshev<MatrixType,
2404  VectorType,
2405  PreconditionerType>::size_type
2407 {
2408  Assert(matrix_ptr != nullptr, ExcNotInitialized());
2409  return matrix_ptr->m();
2410 }
2411 
2412 
2413 
2414 template <typename MatrixType, typename VectorType, typename PreconditionerType>
2415 inline typename PreconditionChebyshev<MatrixType,
2416  VectorType,
2417  PreconditionerType>::size_type
2419 {
2420  Assert(matrix_ptr != nullptr, ExcNotInitialized());
2421  return matrix_ptr->n();
2422 }
2423 
2424 #endif // DOXYGEN
2425 
2426 DEAL_II_NAMESPACE_CLOSE
2427 
2428 #endif
void Tstep(VectorType &x, const VectorType &rhs) const
void Tvmult_add(VectorType &, const VectorType &) const
void reinit(const size_type size, const bool omit_zeroing_entries=false)
static const unsigned int invalid_unsigned_int
Definition: types.h:173
void vmult(VectorType &, const VectorType &) const
void vmult(VectorType &, const VectorType &) const
types::global_dof_index size_type
Definition: precondition.h:965
void Tvmult(VectorType &dst, const VectorType &src) const
Number local_element(const size_type local_index) const
void initialize(const MatrixType &A, const typename BaseClass::AdditionalData &parameters=typename BaseClass::AdditionalData())
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
void vmult(VectorType &, const VectorType &) const
PreconditionRelaxation< MatrixType >::AdditionalData parameters
Definition: precondition.h:806
void step(VectorType &dst, const VectorType &src) const
const MatrixType & matrix
Definition: precondition.h:389
AdditionalData data
size_type m() const
AdditionalData(const double relaxation=1.)
void(MatrixType::*)(VectorType &, const VectorType &) const function_ptr
Definition: precondition.h:369
size_type m() const
static::ExceptionBase & ExcNotInitialized()
void initialize(const MatrixType &matrix, const AdditionalData &additional_data=AdditionalData())
std::shared_ptr< PreconditionerType > preconditioner
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
bool is_empty() const
Definition: index_set.h:1735
AdditionalData(const double relaxation=1.)
void Tstep(VectorType &x, const VectorType &rhs) const
unsigned long long int global_dof_index
Definition: types.h:72
const std::vector< size_type > * permutation
Definition: precondition.h:859
size_type n() const
const_iterator begin() const
const function_ptr precondition
Definition: precondition.h:394
void Tvmult(VectorType &, const VectorType &) const
void vmult_add(VectorType &, const VectorType &) const
void vmult(VectorType &, const VectorType &) const
void initialize(const AdditionalData &parameters)
void step(VectorType &x, const VectorType &rhs) const
static::ExceptionBase & ExcMessage(std::string arg1)
typename MatrixType::size_type size_type
Definition: precondition.h:414
void step(VectorType &x, const VectorType &rhs) const
void vmult(VectorType &dst, const VectorType &src) const
const std::vector< size_type > & inverse_permutation
Definition: precondition.h:802
#define Assert(cond, exc)
Definition: exceptions.h:1227
typename PreconditionRelaxation< MatrixType >::AdditionalData AdditionalData
Definition: precondition.h:669
virtual void add(const Number a) override
void do_transpose_chebyshev_loop(VectorType &dst, const VectorType &src) const
virtual ::IndexSet locally_owned_elements() const override
void Tvmult_add(VectorType &, const VectorType &) const
void Tvmult(VectorType &, const VectorType &) const
void vmult(VectorType &dst, const VectorType &src) const
typename MatrixType::size_type size_type
Definition: precondition.h:770
void Tvmult(VectorType &, const VectorType &) const
void step(VectorType &x, const VectorType &rhs) const
void initialize(const MatrixType &A, const AdditionalData &parameters=AdditionalData())
Threads::Mutex mutex
void estimate_eigenvalues(const VectorType &src) const
void vmult(VectorType &, const VectorType &) const
void Tvmult(VectorType &, const VectorType &) const
const_iterator end() const
AdditionalData(const unsigned int degree=0, const double smoothing_range=0., const bool nonzero_starting=false, const unsigned int eig_cg_n_iterations=8, const double eig_cg_residual=1e-2, const double max_eigenvalue=1)
void Tvmult(VectorType &, const VectorType &) const
virtual Number mean_value() const override
AdditionalData(const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const typename PreconditionRelaxation< MatrixType >::AdditionalData &parameters=typename PreconditionRelaxation< MatrixType >::AdditionalData())
size_type n() const
types::global_dof_index size_type
Definition: precondition.h:202
void Tvmult(VectorType &, const VectorType &) const
SmartPointer< const MatrixType, PreconditionRelaxation< MatrixType > > A
Definition: precondition.h:466
void initialize(const MatrixType &matrix, const AdditionalData &additional_data=AdditionalData())
void vmult(VectorType &, const VectorType &) const
size_type n() const
typename MatrixType::size_type size_type
Definition: precondition.h:674
size_type n() const
const std::vector< size_type > * inverse_permutation
Definition: precondition.h:863
void do_chebyshev_loop(VectorType &dst, const VectorType &src) const
size_type m() const
types::global_dof_index size_type
Definition: precondition.h:83
void Tstep(VectorType &x, const VectorType &rhs) const
typename PreconditionRelaxation< MatrixType >::AdditionalData AdditionalData
Definition: precondition.h:512
void Tstep(VectorType &dst, const VectorType &src) const
const std::vector< size_type > & permutation
Definition: precondition.h:798
size_type nth_index_in_set(const unsigned int local_index) const
Definition: index_set.h:1793
PreconditionUseMatrix(const MatrixType &M, const function_ptr method)
size_type m() const
typename PreconditionRelaxation< MatrixType >::AdditionalData AdditionalData
Definition: precondition.h:600
std::vector< std::size_t > pos_right_of_diagonal
Definition: precondition.h:727
SmartPointer< const MatrixType, PreconditionChebyshev< MatrixType, VectorType, PreconditionerType > > matrix_ptr
void vmult_add(VectorType &, const VectorType &) const
static::ExceptionBase & ExcInternalError()
void initialize(const MatrixType &A, const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const typename PreconditionRelaxation< MatrixType >::AdditionalData &parameters=typename PreconditionRelaxation< MatrixType >::AdditionalData())