Reference documentation for deal.II version 9.1.0-pre
trilinos_precondition.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2008 - 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_trilinos_precondition_h
17 # define dealii_trilinos_precondition_h
18 
19 
20 # include <deal.II/base/config.h>
21 
22 # ifdef DEAL_II_WITH_TRILINOS
23 
24 # include <deal.II/base/subscriptor.h>
25 
26 # include <deal.II/lac/la_parallel_vector.h>
27 # include <deal.II/lac/trilinos_vector.h>
28 
29 # include <memory>
30 
31 # ifdef DEAL_II_WITH_MPI
32 # include <Epetra_MpiComm.h>
33 # else
34 # include <Epetra_SerialComm.h>
35 # endif
36 # include <Epetra_Map.h>
37 # include <Epetra_RowMatrix.h>
38 # include <Epetra_Vector.h>
39 # include <Teuchos_ParameterList.hpp>
40 
41 // forward declarations
42 class Ifpack_Preconditioner;
43 class Ifpack_Chebyshev;
44 namespace ML_Epetra
45 {
46  class MultiLevelPreconditioner;
47 }
48 
49 
50 DEAL_II_NAMESPACE_OPEN
51 
52 // forward declarations
53 template <typename number>
54 class SparseMatrix;
55 template <typename number>
56 class Vector;
57 class SparsityPattern;
58 
63 namespace TrilinosWrappers
64 {
65  // forward declarations
66  class SparseMatrix;
67  class BlockSparseMatrix;
68  class SolverBase;
69 
79  {
80  public:
85 
91  {};
92 
99 
104 
108  ~PreconditionBase() override = default;
109 
114  void
115  clear();
116 
120  MPI_Comm
121  get_mpi_communicator() const;
122 
132  void
133  transpose();
134 
138  virtual void
139  vmult(MPI::Vector &dst, const MPI::Vector &src) const;
140 
144  virtual void
145  Tvmult(MPI::Vector &dst, const MPI::Vector &src) const;
146 
151  virtual void
152  vmult(::Vector<double> &dst, const ::Vector<double> &src) const;
153 
158  virtual void
159  Tvmult(::Vector<double> & dst,
160  const ::Vector<double> &src) const;
161 
166  virtual void
168  const ::LinearAlgebra::distributed::Vector<double> &src) const;
169 
174  virtual void
176  const ::LinearAlgebra::distributed::Vector<double> &src) const;
177 
187  Epetra_Operator &
188  trilinos_operator() const;
190 
195 
200  IndexSet
201  locally_owned_domain_indices() const;
202 
208  IndexSet
209  locally_owned_range_indices() const;
210 
212 
221  DeclException1(ExcNonMatchingMaps,
222  std::string,
223  << "The sparse matrix the preconditioner is based on "
224  << "uses a map that is not compatible to the one in vector "
225  << arg1 << ". Check preconditioner and matrix setup.");
227 
228  friend class SolverBase;
229 
230  protected:
235  std::shared_ptr<Epetra_Operator> preconditioner;
236 
241 # ifdef DEAL_II_WITH_MPI
242  Epetra_MpiComm communicator;
243 # else
244  Epetra_SerialComm communicator;
245 # endif
246 
251  std::shared_ptr<Epetra_Map> vector_distributor;
252  };
253 
254 
272  {
273  public:
286  {
291  AdditionalData(const double omega = 1,
292  const double min_diagonal = 0,
293  const unsigned int n_sweeps = 1);
294 
298  double omega;
299 
307  double min_diagonal;
308 
313  unsigned int n_sweeps;
314  };
315 
320  void
321  initialize(const SparseMatrix & matrix,
322  const AdditionalData &additional_data = AdditionalData());
323  };
324 
325 
326 
354  {
355  public:
370  {
377  AdditionalData(const double omega = 1,
378  const double min_diagonal = 0,
379  const unsigned int overlap = 0,
380  const unsigned int n_sweeps = 1);
381 
386  double omega;
387 
395  double min_diagonal;
396 
401  unsigned int overlap;
402 
407  unsigned int n_sweeps;
408  };
409 
415  void
416  initialize(const SparseMatrix & matrix,
417  const AdditionalData &additional_data = AdditionalData());
418  };
419 
420 
421 
449  {
450  public:
465  {
472  AdditionalData(const double omega = 1,
473  const double min_diagonal = 0,
474  const unsigned int overlap = 0,
475  const unsigned int n_sweeps = 1);
476 
481  double omega;
482 
490  double min_diagonal;
491 
496  unsigned int overlap;
497 
502  unsigned int n_sweeps;
503  };
504 
510  void
511  initialize(const SparseMatrix & matrix,
512  const AdditionalData &additional_data = AdditionalData());
513  };
514 
515 
516 
535  {
536  public:
555  {
561  AdditionalData(const unsigned int block_size = 1,
562  const std::string &block_creation_type = "linear",
563  const double omega = 1,
564  const double min_diagonal = 0,
565  const unsigned int n_sweeps = 1);
566 
570  unsigned int block_size;
571 
579  std::string block_creation_type;
580 
585  double omega;
586 
594  double min_diagonal;
595 
600  unsigned int n_sweeps;
601  };
602 
607  void
608  initialize(const SparseMatrix & matrix,
609  const AdditionalData &additional_data = AdditionalData());
610  };
611 
612 
613 
637  {
638  public:
657  {
665  AdditionalData(const unsigned int block_size = 1,
666  const std::string &block_creation_type = "linear",
667  const double omega = 1,
668  const double min_diagonal = 0,
669  const unsigned int overlap = 0,
670  const unsigned int n_sweeps = 1);
671 
675  unsigned int block_size;
676 
684  std::string block_creation_type;
685 
690  double omega;
691 
699  double min_diagonal;
700 
705  unsigned int overlap;
706 
711  unsigned int n_sweeps;
712  };
713 
719  void
720  initialize(const SparseMatrix & matrix,
721  const AdditionalData &additional_data = AdditionalData());
722  };
723 
724 
725 
749  {
750  public:
769  {
777  AdditionalData(const unsigned int block_size = 1,
778  const std::string &block_creation_type = "linear",
779  const double omega = 1,
780  const double min_diagonal = 0,
781  const unsigned int overlap = 0,
782  const unsigned int n_sweeps = 1);
783 
787  unsigned int block_size;
788 
796  std::string block_creation_type;
797 
802  double omega;
803 
811  double min_diagonal;
812 
817  unsigned int overlap;
818 
823  unsigned int n_sweeps;
824  };
825 
831  void
832  initialize(const SparseMatrix & matrix,
833  const AdditionalData &additional_data = AdditionalData());
834  };
835 
836 
837 
874  {
875  public:
893  {
903  AdditionalData(const unsigned int ic_fill = 0,
904  const double ic_atol = 0.,
905  const double ic_rtol = 1.,
906  const unsigned int overlap = 0);
907 
916  unsigned int ic_fill;
917 
923  double ic_atol;
924 
929  double ic_rtol;
930 
935  unsigned int overlap;
936  };
937 
942  void
943  initialize(const SparseMatrix & matrix,
944  const AdditionalData &additional_data = AdditionalData());
945  };
946 
947 
948 
979  {
980  public:
1019  {
1023  AdditionalData(const unsigned int ilu_fill = 0,
1024  const double ilu_atol = 0.,
1025  const double ilu_rtol = 1.,
1026  const unsigned int overlap = 0);
1027 
1031  unsigned int ilu_fill;
1032 
1037  double ilu_atol;
1038 
1043  double ilu_rtol;
1044 
1048  unsigned int overlap;
1049  };
1050 
1055  void
1056  initialize(const SparseMatrix & matrix,
1057  const AdditionalData &additional_data = AdditionalData());
1058  };
1059 
1060 
1061 
1098  {
1099  public:
1118  {
1129  AdditionalData(const double ilut_drop = 0.,
1130  const unsigned int ilut_fill = 0,
1131  const double ilut_atol = 0.,
1132  const double ilut_rtol = 1.,
1133  const unsigned int overlap = 0);
1134 
1139  double ilut_drop;
1140 
1149  unsigned int ilut_fill;
1150 
1156  double ilut_atol;
1157 
1162  double ilut_rtol;
1163 
1168  unsigned int overlap;
1169  };
1170 
1175  void
1176  initialize(const SparseMatrix & matrix,
1177  const AdditionalData &additional_data = AdditionalData());
1178  };
1179 
1180 
1181 
1201  {
1202  public:
1208  {
1212  AdditionalData(const unsigned int overlap = 0);
1213 
1214 
1219  unsigned int overlap;
1220  };
1221 
1226  void
1227  initialize(const SparseMatrix & matrix,
1228  const AdditionalData &additional_data = AdditionalData());
1229  };
1230 
1231 
1232 
1243  {
1244  public:
1250  {
1254  AdditionalData(const unsigned int degree = 1,
1255  const double max_eigenvalue = 10.,
1256  const double eigenvalue_ratio = 30.,
1257  const double min_eigenvalue = 1.,
1258  const double min_diagonal = 1e-12,
1259  const bool nonzero_starting = false);
1260 
1266  unsigned int degree;
1267 
1273 
1278 
1284 
1290 
1302  };
1303 
1308  void
1309  initialize(const SparseMatrix & matrix,
1310  const AdditionalData &additional_data = AdditionalData());
1311  };
1312 
1313 
1314 
1358  {
1359  public:
1367  {
1372  AdditionalData(const bool elliptic = true,
1373  const bool higher_order_elements = false,
1374  const unsigned int n_cycles = 1,
1375  const bool w_cyle = false,
1376  const double aggregation_threshold = 1e-4,
1377  const std::vector<std::vector<bool>> &constant_modes =
1378  std::vector<std::vector<bool>>(0),
1379  const unsigned int smoother_sweeps = 2,
1380  const unsigned int smoother_overlap = 0,
1381  const bool output_details = false,
1382  const char * smoother_type = "Chebyshev",
1383  const char * coarse_type = "Amesos-KLU");
1384 
1392  bool elliptic;
1393 
1399 
1404  unsigned int n_cycles;
1405 
1410  bool w_cycle;
1411 
1422 
1439  std::vector<std::vector<bool>> constant_modes;
1440 
1451  unsigned int smoother_sweeps;
1452 
1457  unsigned int smoother_overlap;
1458 
1465 
1500  const char *smoother_type;
1501 
1506  const char *coarse_type;
1507  };
1508 
1512  ~PreconditionAMG() override;
1513 
1514 
1520  void
1521  initialize(const SparseMatrix & matrix,
1522  const AdditionalData &additional_data = AdditionalData());
1523 
1542  void
1543  initialize(const Epetra_RowMatrix &matrix,
1544  const AdditionalData & additional_data = AdditionalData());
1545 
1558  void
1559  initialize(const SparseMatrix & matrix,
1560  const Teuchos::ParameterList &ml_parameters);
1561 
1569  void
1570  initialize(const Epetra_RowMatrix & matrix,
1571  const Teuchos::ParameterList &ml_parameters);
1572 
1579  template <typename number>
1580  void
1581  initialize(const ::SparseMatrix<number> &deal_ii_sparse_matrix,
1582  const AdditionalData &additional_data = AdditionalData(),
1583  const double drop_tolerance = 1e-13,
1584  const ::SparsityPattern *use_this_sparsity = nullptr);
1585 
1598  void
1599  reinit();
1600 
1605  void
1606  clear();
1607 
1611  size_type
1612  memory_consumption() const;
1613 
1614  private:
1618  std::shared_ptr<SparseMatrix> trilinos_matrix;
1619  };
1620 
1621 
1622 
1623 # if defined(DOXYGEN) || DEAL_II_TRILINOS_VERSION_GTE(11, 14, 0)
1624 
1642  {
1643  public:
1651  {
1656  AdditionalData(const bool elliptic = true,
1657  const unsigned int n_cycles = 1,
1658  const bool w_cyle = false,
1659  const double aggregation_threshold = 1e-4,
1660  const std::vector<std::vector<bool>> &constant_modes =
1661  std::vector<std::vector<bool>>(0),
1662  const unsigned int smoother_sweeps = 2,
1663  const unsigned int smoother_overlap = 0,
1664  const bool output_details = false,
1665  const char * smoother_type = "Chebyshev",
1666  const char * coarse_type = "Amesos-KLU");
1667 
1675  bool elliptic;
1676 
1681  unsigned int n_cycles;
1682 
1687  bool w_cycle;
1688 
1699 
1706  std::vector<std::vector<bool>> constant_modes;
1707 
1718  unsigned int smoother_sweeps;
1719 
1724  unsigned int smoother_overlap;
1725 
1732 
1767  const char *smoother_type;
1768 
1773  const char *coarse_type;
1774  };
1775 
1780 
1784  ~PreconditionAMGMueLu() override;
1785 
1791  void
1792  initialize(const SparseMatrix & matrix,
1793  const AdditionalData &additional_data = AdditionalData());
1794 
1801  void
1802  initialize(const Epetra_CrsMatrix &matrix,
1803  const AdditionalData & additional_data = AdditionalData());
1804 
1816  void
1817  initialize(const SparseMatrix & matrix,
1818  Teuchos::ParameterList &muelu_parameters);
1819 
1825  void
1826  initialize(const Epetra_CrsMatrix &matrix,
1827  Teuchos::ParameterList &muelu_parameters);
1828 
1835  template <typename number>
1836  void
1837  initialize(const ::SparseMatrix<number> &deal_ii_sparse_matrix,
1838  const AdditionalData &additional_data = AdditionalData(),
1839  const double drop_tolerance = 1e-13,
1840  const ::SparsityPattern *use_this_sparsity = nullptr);
1841 
1846  void
1847  clear();
1848 
1852  size_type
1853  memory_consumption() const;
1854 
1855  private:
1859  std::shared_ptr<SparseMatrix> trilinos_matrix;
1860  };
1861 # endif
1862 
1863 
1864 
1874  {
1875  public:
1881  {};
1882 
1889  void
1890  initialize(const SparseMatrix & matrix,
1891  const AdditionalData &additional_data = AdditionalData());
1892 
1896  void
1897  vmult(MPI::Vector &dst, const MPI::Vector &src) const override;
1898 
1902  void
1903  Tvmult(MPI::Vector &dst, const MPI::Vector &src) const override;
1904 
1909  void
1910  vmult(::Vector<double> & dst,
1911  const ::Vector<double> &src) const override;
1912 
1917  void
1918  Tvmult(::Vector<double> & dst,
1919  const ::Vector<double> &src) const override;
1920 
1925  void
1927  const ::LinearAlgebra::distributed::Vector<double> &src)
1928  const override;
1929 
1935  void
1937  const ::LinearAlgebra::distributed::Vector<double> &src)
1938  const override;
1939  };
1940 
1941 
1942 
1943  // ----------------------- inline and template functions --------------------
1944 
1945 
1946 # ifndef DOXYGEN
1947 
1948 
1949  inline void
1951  {
1952  // This only flips a flag that tells
1953  // Trilinos that any vmult operation
1954  // should be done with the
1955  // transpose. However, the matrix
1956  // structure is not reset.
1957  int ierr;
1958 
1959  if (!preconditioner->UseTranspose())
1960  {
1961  ierr = preconditioner->SetUseTranspose(true);
1962  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1963  }
1964  else
1965  {
1966  ierr = preconditioner->SetUseTranspose(false);
1967  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1968  }
1969  }
1970 
1971 
1972  inline void
1973  PreconditionBase::vmult(MPI::Vector &dst, const MPI::Vector &src) const
1974  {
1975  Assert(dst.vector_partitioner().SameAs(preconditioner->OperatorRangeMap()),
1976  ExcNonMatchingMaps("dst"));
1977  Assert(src.vector_partitioner().SameAs(preconditioner->OperatorDomainMap()),
1978  ExcNonMatchingMaps("src"));
1979 
1980  const int ierr = preconditioner->ApplyInverse(src.trilinos_vector(),
1981  dst.trilinos_vector());
1982  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1983  }
1984 
1985  inline void
1986  PreconditionBase::Tvmult(MPI::Vector &dst, const MPI::Vector &src) const
1987  {
1988  Assert(dst.vector_partitioner().SameAs(preconditioner->OperatorRangeMap()),
1989  ExcNonMatchingMaps("dst"));
1990  Assert(src.vector_partitioner().SameAs(preconditioner->OperatorDomainMap()),
1991  ExcNonMatchingMaps("src"));
1992 
1993  preconditioner->SetUseTranspose(true);
1994  const int ierr = preconditioner->ApplyInverse(src.trilinos_vector(),
1995  dst.trilinos_vector());
1996  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
1997  preconditioner->SetUseTranspose(false);
1998  }
1999 
2000 
2001  // For the implementation of the <code>vmult</code> function with deal.II
2002  // data structures we note that invoking a call of the Trilinos
2003  // preconditioner requires us to use Epetra vectors as well. We do this by
2004  // providing a view, i.e., feed Trilinos with a pointer to the data, so we
2005  // avoid copying the content of the vectors during the iteration (this
2006  // function is only useful when used in serial anyway). In the declaration
2007  // of the right hand side, we need to cast the source vector (that is
2008  // <code>const</code> in all deal.II calls) to non-constant value, as this
2009  // is the way Trilinos wants to have them.
2010  inline void
2011  PreconditionBase::vmult(::Vector<double> & dst,
2012  const ::Vector<double> &src) const
2013  {
2014  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(dst.size()),
2015  preconditioner->OperatorDomainMap().NumMyElements());
2016  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(src.size()),
2017  preconditioner->OperatorRangeMap().NumMyElements());
2018  Epetra_Vector tril_dst(View,
2019  preconditioner->OperatorDomainMap(),
2020  dst.begin());
2021  Epetra_Vector tril_src(View,
2022  preconditioner->OperatorRangeMap(),
2023  const_cast<double *>(src.begin()));
2024 
2025  const int ierr = preconditioner->ApplyInverse(tril_src, tril_dst);
2026  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2027  }
2028 
2029 
2030  inline void
2031  PreconditionBase::Tvmult(::Vector<double> & dst,
2032  const ::Vector<double> &src) const
2033  {
2034  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(dst.size()),
2035  preconditioner->OperatorDomainMap().NumMyElements());
2036  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(src.size()),
2037  preconditioner->OperatorRangeMap().NumMyElements());
2038  Epetra_Vector tril_dst(View,
2039  preconditioner->OperatorDomainMap(),
2040  dst.begin());
2041  Epetra_Vector tril_src(View,
2042  preconditioner->OperatorRangeMap(),
2043  const_cast<double *>(src.begin()));
2044 
2045  preconditioner->SetUseTranspose(true);
2046  const int ierr = preconditioner->ApplyInverse(tril_src, tril_dst);
2047  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2048  preconditioner->SetUseTranspose(false);
2049  }
2050 
2051 
2052 
2053  inline void
2054  PreconditionBase::vmult(
2057  {
2058  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(
2059  dst.local_size()),
2060  preconditioner->OperatorDomainMap().NumMyElements());
2061  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(
2062  src.local_size()),
2063  preconditioner->OperatorRangeMap().NumMyElements());
2064  Epetra_Vector tril_dst(View,
2065  preconditioner->OperatorDomainMap(),
2066  dst.begin());
2067  Epetra_Vector tril_src(View,
2068  preconditioner->OperatorRangeMap(),
2069  const_cast<double *>(src.begin()));
2070 
2071  const int ierr = preconditioner->ApplyInverse(tril_src, tril_dst);
2072  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2073  }
2074 
2075  inline void
2076  PreconditionBase::Tvmult(
2079  {
2080  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(
2081  dst.local_size()),
2082  preconditioner->OperatorDomainMap().NumMyElements());
2083  AssertDimension(static_cast<TrilinosWrappers::types::int_type>(
2084  src.local_size()),
2085  preconditioner->OperatorRangeMap().NumMyElements());
2086  Epetra_Vector tril_dst(View,
2087  preconditioner->OperatorDomainMap(),
2088  dst.begin());
2089  Epetra_Vector tril_src(View,
2090  preconditioner->OperatorRangeMap(),
2091  const_cast<double *>(src.begin()));
2092 
2093  preconditioner->SetUseTranspose(true);
2094  const int ierr = preconditioner->ApplyInverse(tril_src, tril_dst);
2095  AssertThrow(ierr == 0, ExcTrilinosError(ierr));
2096  preconditioner->SetUseTranspose(false);
2097  }
2098 
2099 # endif
2100 
2101 } // namespace TrilinosWrappers
2102 
2103 
2107 DEAL_II_NAMESPACE_CLOSE
2108 
2109 # endif // DEAL_II_WITH_TRILINOS
2110 
2111 #endif // trilinos_precondition_h
2112 /*------------------------- trilinos_precondition.h -------------------------*/
static::ExceptionBase & ExcTrilinosError(int arg1)
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1366
size_type size() const
std::shared_ptr< Epetra_Map > vector_distributor
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
unsigned long long int global_dof_index
Definition: types.h:72
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
#define Assert(cond, exc)
Definition: exceptions.h:1227
const Epetra_Map & vector_partitioner() const
SymmetricTensor< rank_, dim, Number > transpose(const SymmetricTensor< rank_, dim, Number > &t)
iterator begin()
std::shared_ptr< SparseMatrix > trilinos_matrix
std::shared_ptr< SparseMatrix > trilinos_matrix
std::shared_ptr< Epetra_Operator > preconditioner
const Epetra_MultiVector & trilinos_vector() const