LifeV
PreconditionerIfpack.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief Ifpack preconditioner
30 
31  @author Simone Deparis <simone.deparis@epfl.ch>
32  @contributor Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
33  @maintainer Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
34 
35  @date 09-11-2006
36  */
37 
38 #include <lifev/core/LifeV.hpp>
40 
41 namespace LifeV
42 {
43 
44 // ===================================================
45 // Constructors & Destructor
46 // ===================================================
47 PreconditionerIfpack::PreconditionerIfpack ( std::shared_ptr<Epetra_Comm> comm ) :
48  super (),
50  M_comm ( comm ),
51  M_overlapLevel (0),
52  M_operator()
53 {
54 
55 }
56 
58 {
59 
60 }
61 
62 
63 // ===================================================
64 // Methods
65 // ===================================================
66 Int
67 PreconditionerIfpack::buildPreconditioner ( operator_type& matrix )
68 {
69  M_operator = matrix->matrixPtr();
70 
71  M_overlapLevel = this->M_list.get ( "overlap level", -1 );
72 
73  M_precType = this->M_list.get ( "prectype", "Amesos" );
74 
75 #ifdef HAVE_IFPACK_DYNAMIC_FACTORY
76  Ifpack_DynamicFactory factory;
77 #else
78  Ifpack factory;
79 #endif
80 
81  M_preconditioner.reset ( factory.Create ( M_precType, M_operator.get(), M_overlapLevel ) );
82 
83  M_precType += "_Ifpack";
84 
85  if ( !M_preconditioner.get() )
86  {
87  ERROR_MSG ( "Preconditioner not set, something went wrong in its computation\n" );
88  }
89 
90  IFPACK_CHK_ERR ( M_preconditioner->SetParameters ( this->M_list ) );
91  IFPACK_CHK_ERR ( M_preconditioner->Initialize() );
92  IFPACK_CHK_ERR ( M_preconditioner->Compute() );
93 
94  this->M_preconditionerCreated = true;
95 
96  return ( EXIT_SUCCESS );
97 }
98 
99 void
101 {
102  M_operator.reset();
103  M_preconditioner.reset();
104 
105  this->M_preconditionerCreated = false;
106 }
107 
108 void
110  const GetPot& dataFile,
111  const std::string& section,
112  const std::string& subSection )
113 {
114  createIfpackList ( list, dataFile, section, subSection, M_comm->MyPID() == 0 );
115 }
116 
117 void
119  const GetPot& dataFile,
120  const std::string& section,
121  const std::string& subSection,
122  const bool& verbose )
123 {
124  // See http://trilinos.sandia.gov/packages/docs/r9.0/packages/ifpack/doc/html/index.html
125  // for more informations on the parameters
126 
127  Int overlapLevel = dataFile ( (section + "/" + subSection + "/overlap").data(), 0 );
128 
129  std::string precType = dataFile ( (section + "/" + subSection + "/prectype").data(), "Amesos" );
130 
131  list.set ( "prectype", precType );
132  list.set ( "overlap level", overlapLevel );
133 
134  bool displayList = dataFile ( (section + "/displayList").data(), false );
135 
136  std::string relaxationType = dataFile ( (section + "/" + subSection + "/relaxation/type").data(), "Jacobi" );
137  Int relaxationSweeps = dataFile ( (section + "/" + subSection + "/relaxation/sweeps").data(), 1 );
138  Real relaxationDampingFactor = dataFile ( (section + "/" + subSection + "/relaxation/damping_factor").data(), 1.0 );
139  Real relaxationMinDiagValue = dataFile ( (section + "/" + subSection + "/relaxation/min_diagonal_value").data(), 0.0 );
140  bool relaxationZeroStartSolution = dataFile ( (section + "/" + subSection + "/relaxation/zero_starting_solution").data(), true );
141 
142  list.set ( "relaxation: type", relaxationType );
143  list.set ( "relaxation: sweeps", relaxationSweeps );
144  list.set ( "relaxation: damping factor", relaxationDampingFactor );
145  list.set ( "relaxation: min diagonal value", relaxationMinDiagValue );
146  list.set ( "relaxation: zero starting solution", relaxationZeroStartSolution );
147 
148  std::string partitionerType = dataFile ( (section + "/" + subSection + "/partitioner/type").data(), "metis" );
149  Int partitionerOverlap = dataFile ( (section + "/" + subSection + "/partitioner/overlap").data(), 0 );
150  Int partitionerLocalParts = dataFile ( (section + "/" + subSection + "/partitioner/local_parts").data(), 1 );
151  Int partitionerRootNode = dataFile ( (section + "/" + subSection + "/partitioner/root_node").data(), 0 );
152  bool partitionerUseSymmGraph = dataFile ( (section + "/" + subSection + "/partitioner/use_symmetric_graph").data(), true );
153 
154  list.set ( "partitioner: type", partitionerType );
155  list.set ( "partitioner: overlap", partitionerOverlap );
156  list.set ( "partitioner: local parts", partitionerLocalParts );
157  list.set ( "partitioner: root node", partitionerRootNode );
158  list.set ( "partitioner: use symmetric graph", partitionerUseSymmGraph );
159 
160  std::string amesosSolverType = dataFile ( (section + "/" + subSection + "/amesos/solvertype").data(), "Amesos_KLU" );
161 
162  list.set ( "amesos: solver type", amesosSolverType );
163 
164  Int levelOfFill = dataFile ( (section + "/" + subSection + "/fact/level-of-fill").data(), 4 );
165  Real ILUTlevelOfFill = dataFile ( (section + "/" + subSection + "/fact/ilut_level-of-fill").data(), 4. );
166  Real athr = dataFile ( (section + "/" + subSection + "/fact/absolute_threshold").data(), 0. );
167  Real rthr = dataFile ( (section + "/" + subSection + "/fact/relative_threshold").data(), 1. );
168  Real relaxValue = dataFile ( (section + "/" + subSection + "/fact/relax_value").data(), 0. );
169  Real dropTolerance = dataFile ( (section + "/" + subSection + "/fact/drop_tolerance").data(), 1e-5 );
170 
171  list.set ( "fact: drop tolerance", dropTolerance );
172  list.set ( "fact: level-of-fill", levelOfFill );
173  list.set ( "fact: ilut level-of-fill", ILUTlevelOfFill );
174  list.set ( "fact: absolute threshold", athr );
175  list.set ( "fact: relative threshold", rthr );
176  list.set ( "fact: relax value", relaxValue );
177 
178  Int combineMode = dataFile ( (section + "/" + subSection + "/schwarz/combine_mode").data(), 0 );
179  Epetra_CombineMode schwarzCombineMode;
180 
181  switch (combineMode)
182  {
183  case 0 :
184  schwarzCombineMode = Add;
185  break;
186  case 1 :
187  schwarzCombineMode = Zero;
188  break;
189  case 2 :
190  schwarzCombineMode = Insert;
191  break;
192  case 3 :
193  schwarzCombineMode = Average;
194  break;
195  case 4 :
196  schwarzCombineMode = AbsMax;
197  break;
198  default:
199  schwarzCombineMode = Zero;
200  }
201 
202  bool schwarzComputeCondest = dataFile ( (section + "/" + subSection + "/schwarz/compute_condest").data(), true );
203  std::string schwarzReorderingType = dataFile ( (section + "/" + subSection + "/schwarz/reordering_type").data(), "none" );
204  bool schwarzFilterSingletons = dataFile ( (section + "/" + subSection + "/schwarz/filter_singletons").data(), true );
205 
206  list.set ( "schwarz: combine mode", schwarzCombineMode);
207  list.set ( "schwarz: compute condest", schwarzComputeCondest);
208  list.set ( "schwarz: reordering type", schwarzReorderingType);
209  list.set ( "schwarz: filter singletons", schwarzFilterSingletons);
210 
211  // New parameters related to ShyLU and parallel subdomain problems
212  Int subdomainSize = dataFile ( (section + "/" + subSection + "/subdomain/number_of_processors").data(), 1);
213  list.set ("subdomain: number-of-processors", subdomainSize);
214 
215  // ShyLU parameters
216  Teuchos::ParameterList shyluList;
217  std::string outerSolverLibrary = dataFile ( (section + "/" + subSection + "/shylu/outer_solver_library").data(), "Belos");
218  shyluList.set ("Outer Solver Library", outerSolverLibrary);
219  std::string separatorType = dataFile ( (section + "/" + subSection + "/shylu/separator_type").data(), "Wide");
220  shyluList.set ("Separator Type", separatorType);
221  std::string schurApproxMethod = dataFile ( (section + "/" + subSection + "/shylu/schur_approx_method").data(), "A22AndBlockDiagonals");
222  shyluList.set ("Schur Approximation Method", schurApproxMethod);
223  double relativeThreshold = dataFile ( (section + "/" + subSection + "/shylu/relative_threshold").data(), 1e-3);
224  shyluList.set ("Relative Threshold", relativeThreshold);
225  double diagonalFactor = dataFile ( (section + "/" + subSection + "/shylu/diagonal_factor").data(), 0.02);
226  shyluList.set ("Diagonal Factor", diagonalFactor);
227  std::string schurComplementSolver = dataFile ( (section + "/" + subSection + "/shylu/schur_complement_solver").data(), "AztecOO-Exact");
228  shyluList.set ("Schur Complement Solver", schurComplementSolver);
229  std::string schurAmesosSolver = dataFile ( (section + "/" + subSection + "/shylu/schur_amesos_solver").data(), "Amesos_Klu");
230  shyluList.set ("Schur Amesos Solver", schurAmesosSolver);
231  std::string schurPrec = dataFile ( (section + "/" + subSection + "/shylu/schur_prec").data(), "ILU stand-alone");
232  shyluList.set ("Schur Preconditioner", schurPrec);
233  Int shyluSymmetry = dataFile ( (section + "/" + subSection + "/shylu/symmetry").data(), 1);
234  shyluList.set ("Symmetry", shyluSymmetry);
235  Int innerMaxIter = dataFile ( (section + "/" + subSection + "/shylu/inner_solver_iterations").data(), 5);
236  shyluList.set ("Inner Solver MaxIters", innerMaxIter);
237  double innerTol = dataFile ( (section + "/" + subSection + "/shylu/inner_solver_tolerance").data(), 1e-10);
238  shyluList.set ("Inner Solver Tolerance", innerTol);
239  bool silentSubiterations = dataFile ( (section + "/" + subSection + "/shylu/silent_subiterations").data(), true);
240  shyluList.set ("Silent subiterations", silentSubiterations);
241  std::string shyluDiagSolver = dataFile ( (section + "/" + subSection + "/shylu/diag_solver").data(), "Amesos_Klu");
242  shyluList.set ("Diagonal Block Solver", shyluDiagSolver);
243  double iqrKrylovDim = dataFile ( (section + "/" + subSection + "/shylu/iqr_krylov_dim").data(), 0.5);
244  shyluList.set ("IQR Krylov Dim", iqrKrylovDim);
245  Int iqrNumIter = dataFile ( (section + "/" + subSection + "/shylu/iqr_num_iter").data(), 0);
246  shyluList.set ("IQR Number Iterations", iqrNumIter);
247  bool iqrScaling = dataFile ( (section + "/" + subSection + "/shylu/iqr_scaling").data(), true);
248  shyluList.set ("IQR Scaling", iqrScaling);
249  std::string iqrInitialPrecType = dataFile ( (section + "/" + subSection + "/shylu/iqr_initial_prec_type").data(), "Amesos");
250  shyluList.set ("IQR Initial Prec Type", iqrInitialPrecType);
251  std::string iqrInitialPrecAmesosType = dataFile ( (section + "/" + subSection + "/shylu/iqr_initial_prec_amesos_type").data(), "Amesos_Klu");
252  shyluList.set ("IQR Initial Prec Amesos Type", iqrInitialPrecAmesosType);
253 
254  list.set ("ShyLU list", shyluList);
255 
256  if ( displayList && verbose )
257  {
258  std::cout << "Ifpack parameters list:" << std::endl;
259  std::cout << "-----------------------------" << std::endl;
260  list.print ( std::cout );
261  std::cout << "-----------------------------" << std::endl;
262  }
263 }
264 
265 Int
266 PreconditionerIfpack::ApplyInverse ( const Epetra_MultiVector& vector1, Epetra_MultiVector& vector2 ) const
267 {
268  return M_preconditioner->ApplyInverse ( vector1, vector2 );
269 }
270 
271 Int
272 PreconditionerIfpack::Apply ( const Epetra_MultiVector& vector1, Epetra_MultiVector& vector2 ) const
273 {
274  return M_preconditioner->Apply ( vector1, vector2 );
275 }
276 
277 void
278 PreconditionerIfpack::showMe ( std::ostream& output ) const
279 {
280  output << "showMe must be implemented for the PreconditionerIfpack class" << std::endl;
281 }
282 
283 // ===================================================
284 // Set Methods
285 // ===================================================
286 void
288  const std::string& section )
289 {
290  createIfpackList ( this->M_list, dataFile, section, "ifpack", M_comm->MyPID() == 0 );
291 }
292 
293 Int
294 PreconditionerIfpack::SetUseTranspose ( bool useTranspose )
295 {
296  return M_preconditioner->SetUseTranspose ( useTranspose );
297 }
298 
299 // ===================================================
300 // Get Methods
301 // ===================================================
302 Real
304 {
305  return M_preconditioner->Condest();
306 }
307 
310 {
311  return M_preconditioner.get();
312 }
313 
316 {
317  return M_preconditioner;
318 }
319 
320 std::string
322 {
323  return M_precType;
324 }
325 
326 const Int&
328 {
329  return M_overlapLevel;
330 }
331 
332 bool
334 {
335  return M_preconditioner->UseTranspose();
336 }
337 
338 const Epetra_Map&
340 {
341  return M_preconditioner->OperatorRangeMap();
342 }
343 
344 const Epetra_Map&
346 {
347  return M_preconditioner->OperatorDomainMap();
348 }
349 
350 } // namespace LifeV
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
virtual void showMe(std::ostream &output=std::cout) const
Show informations about the preconditioner.
void updateInverseJacobian(const UInt &iQuadPt)
Int buildPreconditioner(operator_type &matrix)
Build a preconditioner based on the given matrix.
static void createIfpackList(list_Type &list, const GetPot &dataFile, const std::string &section, const std::string &subSection="ifpack", const bool &verbose=true)
Create the list of parameters of the preconditioner.
PreconditionerIfpack(std::shared_ptr< Epetra_Comm > comm=std::shared_ptr< Epetra_Comm >(new Epetra_MpiComm(MPI_COMM_WORLD)))
Empty constructor.
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
Epetra_Operator prec_raw_type
Real condest()
Return An estimation of the condition number of the preconditioner.
virtual void createParametersList(list_Type &list, const GetPot &dataFile, const std::string &section, const std::string &subSection)
Create the list of parameters of the preconditioner.
const Epetra_Map & OperatorRangeMap() const
Return the Range map of the operator.
const Int & getOverlapLevel() const
Return the overlap level.
bool UseTranspose()
Return true if the preconditioner is transposed.
super::prec_type preconditionerPtr()
Return a shared pointer on the preconditioner.
virtual ~PreconditionerIfpack()
Destructor.
Preconditioner(const commPtr_Type &comm=commPtr_Type())
Constructor.
double Real
Generic real data.
Definition: LifeV.hpp:175
Int SetUseTranspose(bool useTranspose=false)
Set the matrix to be used transposed (or not)
Teuchos::ParameterList list_Type
Preconditioner - Abstract preconditioner class.
const Epetra_Map & OperatorDomainMap() const
Return the Domain map of the operator.
std::shared_ptr< prec_raw_type > prec_type
void resetPreconditioner()
Reset the preconditioner.
virtual Int ApplyInverse(const Epetra_MultiVector &vector1, Epetra_MultiVector &vector2) const
Apply the inverse of the preconditioner on vector1 and store the result in vector2.
virtual Int Apply(const Epetra_MultiVector &vector1, Epetra_MultiVector &vector2) const
Apply the inverse of the preconditioner on vector1 and store the result in vector2.
void setDataFromGetPot(const GetPot &dataFile, const std::string &section)
Set the data of the preconditioner using a GetPot object.
super::prec_raw_type * preconditioner()
Return a raw pointer on the preconditioner.
std::string preconditionerType()
Return the type of preconditioner.