HermesCommon  3.0
precond_ifpack.cpp
Go to the documentation of this file.
1 // This file is part of HermesCommon
2 //
3 // Hermes2D is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // Hermes2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
18 #include "config.h"
19 #ifdef HAVE_IFPACK
20 #include "precond_ifpack.h"
21 #include "Ifpack_PointRelaxation.h"
22 #include "Ifpack_BlockRelaxation.h"
23 #include "Ifpack_DenseContainer.h"
24 #include "Ifpack_AdditiveSchwarz.h"
25 #include "Ifpack_ILU.h"
26 #include "Ifpack_ILUT.h"
27 #include "Ifpack_IC.h"
28 #include "Ifpack_ICT.h"
29 #include "Ifpack_Graph_Epetra_CrsGraph.h"
30 
31 namespace Hermes
32 {
33  namespace Preconditioners
34  {
35  template<typename Scalar>
36  IfpackPrecond<Scalar>::IfpackPrecond(const char *cls, const char *type)
37  {
38  this->prec = nullptr;
39  this->owner = true;
40  this->mat = nullptr;
41 
42  this->cls = cls;
43  this->type = type;
44  }
45 
46  template<typename Scalar>
47  IfpackPrecond<Scalar>::IfpackPrecond(const char *cls, const char *type, int overlap)
48  {
49  this->prec = nullptr;
50  this->owner = true;
51  this->mat = nullptr;
52 
53  this->cls = cls;
54  this->type = type;
55  this->overlap = overlap;
56  }
57 
58  template<typename Scalar>
59  IfpackPrecond<Scalar>::IfpackPrecond(Ifpack_Preconditioner *ipc)
60  {
61  this->prec = ipc;
62  this->owner = false;
63  // FIXME: take the matrix from ipc
64  this->mat = nullptr;
65  }
66 
67  template<typename Scalar>
69  {
70  if (owner) delete prec;
71  }
72 
73  template<typename Scalar>
74  void IfpackPrecond<Scalar>::set_param(const char *name, const char *value)
75  {
76  ilist.set(name, value);
77  }
78 
79  template<typename Scalar>
80  void IfpackPrecond<Scalar>::set_param(const char *name, int value)
81  {
82  ilist.set(name, value);
83  }
84 
85  template<typename Scalar>
86  void IfpackPrecond<Scalar>::set_param(const char *name, double value)
87  {
88  ilist.set(name, value);
89  }
90 
91  template<typename Scalar>
93  {
94  EpetraMatrix<Scalar> *mt = static_cast<EpetraMatrix<Scalar> *>(m);
95  assert(mt != nullptr);
96  mat = mt;
97  if (strcmp(cls, "point-relax") == 0)
98  {
99  create_point_relax(mat, type);
100  apply_params();
101  initialize();
102  }
103  else if (strcmp(cls, "block-relax") == 0)
104  {
105  create_block_relax(mat, type);
106  apply_params();
107  }
108  else if (strcmp(cls, "add-schwartz") == 0)
109  {
110  create_add_schwartz(mat, type, overlap);
111  apply_params();
112  initialize();
113  }
114  }
115 
116  template<typename Scalar>
118  {
119  prec = new Ifpack_PointRelaxation(a->mat);
120  ilist.set("relaxation: type", name);
121  }
122 
123  template<typename Scalar>
125  {
126  Teuchos::RCP<const Epetra_CrsGraph> rgraph = Teuchos::rcp(&(a->mat->Graph()));
127  Ifpack_Graph *graph = new Ifpack_Graph_Epetra_CrsGraph(rgraph);
128 
129  Ifpack_Partitioner *partitioner = new Ifpack_GreedyPartitioner(graph);
130 
131  Teuchos::ParameterList list;
132  //\todo parametrize me
133  list.set("partitioner: local parts", 1000);
134  partitioner->SetParameters(list);
135  partitioner->Compute();
136 
137  prec = new Ifpack_BlockRelaxation<Ifpack_DenseContainer>(a->mat);
138  ilist.set("relaxation: type", name);
139 
140  rgraph.release();
141  }
142 
143  template<typename Scalar>
144  void IfpackPrecond<Scalar>::create_add_schwartz(EpetraMatrix<Scalar> *a, const char *name, int overlap)
145  {
146  if (strcasecmp(name, "ilu") == 0)
147  {
148  prec = new Ifpack_AdditiveSchwarz<Ifpack_ILU>(a->mat, overlap);
149  }
150  else if (strcasecmp(name, "ilut") == 0)
151  {
152  prec = new Ifpack_AdditiveSchwarz<Ifpack_ILUT>(a->mat, overlap);
153  }
154  else if (strcasecmp(name, "ic") == 0)
155  {
156  prec = new Ifpack_AdditiveSchwarz<Ifpack_IC>(a->mat, overlap);
157  }
158  else if (strcasecmp(name, "ict") == 0)
159  {
160  prec = new Ifpack_AdditiveSchwarz<Ifpack_ICT>(a->mat, overlap);
161  }
162  else
163  prec = nullptr;
164  }
165 
166  template<typename Scalar>
168  {
169  assert(prec != nullptr);
170  return prec->Initialize();
171  }
172 
173  template<typename Scalar>
175  {
176  assert(prec != nullptr);
177  prec->Compute();
178  }
179 
180  template<typename Scalar>
182  {
183  prec->SetParameters(ilist);
184  }
185 
186  template<typename Scalar>
187  int IfpackPrecond<Scalar>::ApplyInverse(const Epetra_MultiVector &r, Epetra_MultiVector &z) const
188  {
189  assert(prec != nullptr);
190  return prec->ApplyInverse(r, z);
191  }
192 
193  template<typename Scalar>
194  const Epetra_Comm &IfpackPrecond<Scalar>::Comm() const
195  {
196  return mat->mat->Comm();
197  }
198 
199  template<typename Scalar>
200  const Epetra_Map &IfpackPrecond<Scalar>::OperatorDomainMap() const
201  {
202  return mat->mat->OperatorDomainMap();
203  }
204 
205  template<typename Scalar>
206  const Epetra_Map &IfpackPrecond<Scalar>::OperatorRangeMap() const
207  {
208  return mat->mat->OperatorRangeMap();
209  }
210  template class HERMES_API IfpackPrecond < double > ;
211  template class HERMES_API IfpackPrecond < std::complex<double> > ;
212  }
213 }
214 #endif
General (abstract) matrix representation in Hermes.
Definition: matrix.h:36
General namespace for the Hermes library.
Preconditioners built on IFPACK.
Definition: epetra.h:50
IFPACK (Trilinos package) preconditioners interface.
IfpackPrecond(const char *cls, const char *type="Jacobi")