LifeV
BelosOperator.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 BelosOperator
30 
31  @author Umberto Villa <umberto.villa@gmail.com>
32 
33  @date 28-09-2010
34  */
35 
36 #include<lifev/core/operator/BelosOperator.hpp>
37 
38 #include <BelosBlockCGSolMgr.hpp>
39 #include <BelosBlockGmresSolMgr.hpp>
40 #include <BelosGCRODRSolMgr.hpp>
41 #include <BelosGmresPolySolMgr.hpp>
42 #include <BelosPCPGSolMgr.hpp>
43 #include <BelosPseudoBlockCGSolMgr.hpp>
44 #include <BelosPseudoBlockGmresSolMgr.hpp>
45 #ifdef HAVE_TRILINOS_GT_10_6
46 #include <BelosMinresSolMgr.hpp>
47 #endif
48 #include <BelosRCGSolMgr.hpp>
49 #include <BelosTFQMRSolMgr.hpp>
50 #include "Teuchos_RCPBoostSharedPtrConversions.hpp"
51 
52 namespace LifeV
53 {
54 namespace Operators
55 {
56 
60 {
61  M_name = "BelosOperator";
62 }
63 
65 {
66  M_belosPrec = Teuchos::null;
67  M_linProblem = Teuchos::null;
68  M_solverManager = Teuchos::null;
69 }
70 
72 {
73 
74  Teuchos::RCP<vector_Type> Xcopy ( new vector_Type ( X ) );
75  Y.PutScalar ( 0.0 );
76  bool set = M_linProblem->setProblem ( Teuchos::rcp ( &Y, false ), Xcopy );
77  if ( set == false )
78  {
79  std::cout << std::endl << "SLV- ERROR: Belos::LinearProblem failed to set up correctly!" << std::endl;
80  return -12;
81  }
82 
83  M_solverManager->setProblem ( M_linProblem );
84 
85 
86  // Solving the system
87  Belos::ReturnType ret = M_solverManager->solve();
88 
89  // Update the number of performed iterations
90  M_numIterations = M_solverManager->getNumIters();
91 
92  // Update of the status
93  if ( M_solverManager->isLOADetected() )
94  {
96  }
97  else
98  {
100  }
101 
102  if ( ret == Belos::Converged )
103  {
104  M_converged = yes;
105  return 0;
106  }
107  else
108  {
109  M_converged = no;
110  return -1;
111  }
112 
113 }
114 
116 {
117  Teuchos::RCP<OP> tmpPtr ( M_oper.get(), false );
118  M_linProblem->setOperator ( tmpPtr );
119 }
120 
122 {
123  Teuchos::RCP<OP> tmpPtr ( M_prec.get(), false );
124  M_belosPrec = Teuchos::rcp ( new Belos::EpetraPrecOp ( tmpPtr ), true );
125 
126  // The line below produces a memory leak; It has been kept as an example to illustrate
127  // why it has been changed.
128  // M_belosPrec = Teuchos::rcp( new Belos::EpetraPrecOp( Teuchos::rcp( M_prec ) ), false );
129 }
130 
132 {
133  if ( !M_pList->sublist ( "Trilinos: Belos List" ).isParameter ( "Verbosity" ) )
134  M_pList->sublist ( "Trilinos: Belos List" ).set ( "Verbosity", Belos::Errors + Belos::Warnings +
135  Belos::TimingDetails + Belos::StatusTestDetails );
136 
137  if ( M_tolerance > 0 )
138  {
139  M_pList->sublist ( "Trilinos: Belos List" ).set ( "Convergence Tolerance", M_tolerance );
140  }
141 
142  std::string solverType ( M_pList->get<std::string> ( "Solver Manager Type" ) );
144  M_solverManager->setParameters ( sublist ( M_pList, "Trilinos: Belos List", true ) );
145 
146  std::string precSideStr ( M_pList->get<std::string> ( "Preconditioner Side" ) );
147  PreconditionerSide precSide ( getPreconditionerSideFromString ( precSideStr ) );
148 
149  switch (precSide)
150  {
151  case None:
152  break;
153  case Left:
154  M_linProblem->setLeftPrec ( M_belosPrec );
155  break;
156  case Right:
157  M_linProblem->setRightPrec ( M_belosPrec );
158  break;
159  default:
160  exit (1);
161  }
162 
163 }
164 
165 //============================================================================//
166 // Protected or Private Methods //
167 //============================================================================//
168 void BelosOperator::allocateSolver ( const SolverManagerType& solverManagerType )
169 {
170  // If a SolverManager already exists we simply clean it!
171  if ( !M_solverManager.is_null() )
172  {
173  M_solverManager = Teuchos::null;
174  }
175 
176  switch ( solverManagerType )
177  {
178  case NotAValidSolverManager:
179  std::cout << "SLV- ERROR: Not a Valid Solver Manager \n";
180  exit (1);
181  break;
182  case BlockCG:
183  // Create the block CG iteration
184  M_solverManager = rcp ( new Belos::BlockCGSolMgr<Real, vector_Type, operator_Type>() );
185  break;
186  case PseudoBlockCG:
187  // Create the pseudo block CG iteration
188  M_solverManager = rcp ( new Belos::PseudoBlockCGSolMgr<Real, vector_Type, operator_Type>() );
189  break;
190  case RCG:
191  M_solverManager = rcp ( new Belos::RCGSolMgr<Real, vector_Type, operator_Type>() );
192  break;
193  case BlockGmres:
194  M_solverManager = rcp ( new Belos::BlockGmresSolMgr<Real, vector_Type, operator_Type>() );
195  break;
196  case PseudoBlockGmres:
197  M_solverManager = rcp ( new Belos::PseudoBlockGmresSolMgr<Real, vector_Type, operator_Type>() );
198  break;
199  case GmresPoly:
200  M_solverManager = rcp ( new Belos::GmresPolySolMgr<Real, vector_Type, operator_Type>() );
201  break;
202  case GCRODR:
203  M_solverManager = rcp ( new Belos::GCRODRSolMgr<Real, vector_Type, operator_Type>() );
204  break;
205  case PCPG:
206  M_solverManager = rcp ( new Belos::PCPGSolMgr<Real, vector_Type, operator_Type>() );
207  break;
208  case TFQMR:
209  // Create TFQMR iteration
210  M_solverManager = rcp ( new Belos::TFQMRSolMgr<Real, vector_Type, operator_Type>() );
211  break;
212 #ifdef HAVE_TRILINOS_GT_10_6
213  case MINRES:
214  // Create MINRES iteration
215  M_solverManager = rcp ( new Belos::MinresSolMgr<Real, vector_Type, operator_Type>() );
216  break;
217 #endif
218  default:
219  ERROR_MSG ("Belos solver not found!");
220  }
221 
222 }
223 
226 {
227  if ( str == "BlockCG" )
228  {
229  return BlockCG;
230  }
231  else if ( str == "PseudoBlockCG" )
232  {
233  return PseudoBlockCG;
234  }
235  else if ( str == "RCG" )
236  {
237  return RCG;
238  }
239  else if ( str == "BlockGmres" )
240  {
241  return BlockGmres;
242  }
243  else if ( str == "PseudoBlockGmres" )
244  {
245  return PseudoBlockGmres;
246  }
247  else if ( str == "GmresPoly" )
248  {
249  return GmresPoly;
250  }
251  else if ( str == "GCRODR" )
252  {
253  return GCRODR;
254  }
255  else if ( str == "PCPG" )
256  {
257  return PCPG;
258  }
259  else if ( str == "TFQMR" )
260  {
261  return TFQMR;
262  }
263  else if ( str == "MINRES" )
264  {
265  return MINRES;
266  }
267  else
268  {
269  return NotAValidSolverManager;
270  }
271 }
272 
275 {
276  if ( str == "Right" || str == "right" )
277  {
278  return Right;
279  }
280  else if ( str == "Left" || str == "left" )
281  {
282  return Left;
283  }
284  else
285  {
286  return None;
287  }
288 }
289 
290 void
292 {
293  M_solverManager->reset (Belos::Problem);
294  M_belosPrec = Teuchos::null;
295 }
296 
297 } // Namespace Operators
298 
299 } // Namespace LifeV
SolverOperatorStatusType M_lossOfAccuracy
Status to see if there is a loss of accuracy.
SolverOperator(std::shared_ptr< Epetra_Comm > comm=std::shared_ptr< Epetra_Comm >(new Epetra_MpiComm(MPI_COMM_WORLD)))
Class which defines the interface of an Invertible Linear Operator through belos. ...
static PreconditionerSide getPreconditionerSideFromString(const std::string &str)
void updateInverseJacobian(const UInt &iQuadPt)
SolverOperatorStatusType M_converged
Status to see if the solver has converged.
static SolverManagerType getSolverManagerTypeFromString(const std::string &str)
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
virtual int doApplyInverse(const vector_Type &X, vector_Type &Y) const
BelosOperator()
null constructor and destructor
Real M_tolerance
Solver tolerance.
void allocateSolver(const SolverManagerType &solverManagerType)