dune-fem  2.4.1-rc
istlsolver.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_ISTLSOLVERS_HH
2 #define DUNE_FEM_ISTLSOLVERS_HH
3 
4 #include <limits>
5 
10 
11 
12 #if HAVE_DUNE_ISTL
13 #include <dune/istl/preconditioners.hh>
14 #include <dune/istl/solvers.hh>
15 #include <dune/istl/superlu.hh>
16 
17 namespace Dune
18 {
19 
20  namespace Fem
21  {
22 
23  //=====================================================================
24  // Implementation for ISTL-matrix based operator
25  //=====================================================================
26 
31  // DefaultSolverCaller
32  // -------------------
33 
34  template< class OperatorImp, class DiscreteFunction, class SolverCaller >
35  struct DefaultSolverCaller
36  {
37 
38  static std::pair< int, double >
39  call ( const OperatorImp &op,
40  const DiscreteFunction &arg, DiscreteFunction &dest,
41  double reduction, double absLimit, int maxIter, bool verbose,
42  const ParameterReader &parameter )
43  {
44  typedef typename OperatorImp :: MatrixAdapterType MatrixAdapterType;
45  MatrixAdapterType matrix = op.systemMatrix().matrixAdapter();
46 
47  typedef typename DiscreteFunction :: DofStorageType BlockVectorType;
48 
49  // verbose only in verbose mode and for rank 0
50  int verb = (verbose && (dest.space().gridPart().comm().rank() == 0)) ? 2 : 0;
51 
52  if( absLimit < std::numeric_limits< double >::max() )
53  {
54  const double residuum = matrix.residuum( arg.blockVector(), dest.blockVector() );
55  reduction = (residuum > 0) ? absLimit/ residuum : 1e-3;
56 
57  if( verbose && (dest.space().gridPart().comm().rank() == 0) )
58  std::cout << SolverCaller::name() <<": reduction: " << reduction << ", residuum: " << residuum << ", absolut limit: " << absLimit << std::endl;
59  }
60 
61  typename SolverCaller :: SolverType solver( matrix, matrix.scp(), matrix.preconditionAdapter(), reduction, maxIter, verb );
62 
63  // copy right hand side since ISTL is overwriting it
64  BlockVectorType rhs( arg.blockVector() );
65 
66  InverseOperatorResult returnInfo;
67 
68  // call solver
69  solver.apply( dest.blockVector(), rhs, returnInfo );
70 
71  return std::pair< int, double > ( returnInfo.iterations, matrix.averageCommTime() );
72  }
73 
74  };
75 
76 
77  // ISTLInverseOp
78  // Baseclass for each ISTL solver
79  // -------------
80 
81  template< class DF, class Op, class SolverCaller >
82  struct ISTLInverseOp
83  : public Operator< DF, DF >
84  {
85  public:
86  typedef DF DiscreteFunctionType;
87  typedef DiscreteFunctionType DestinationType;
88  typedef Op OperatorType;
89  typedef SolverCaller SolverCallerType;
90 
101  ISTLInverseOp ( const OperatorType &op,
102  double reduction, double absLimit, int maxIter, bool verbose,
103  const ParameterReader &parameter = Parameter::container() )
104  : op_( op ),
105  reduction_( reduction ),
106  absLimit_( absLimit ),
107  maxIter_( maxIter ),
108  verbose_( verbose ),
109  iterations_( 0 ),
110  averageCommTime_( 0.0 ),
111  parameter_( parameter )
112  {}
113 
121  ISTLInverseOp ( const OperatorType &op,
122  double reduction, double absLimit, int maxIter,
123  const ParameterReader &parameter = Parameter::container() )
124  : op_( op ),
125  reduction_( reduction ),
126  absLimit_ ( absLimit ),
127  maxIter_( maxIter ),
128  verbose_( parameter.getValue< bool >( "fem.solver.verbose", false ) ),
129  iterations_( 0 ),
130  averageCommTime_( 0.0 ),
131  parameter_( parameter )
132  {}
133 
134  ISTLInverseOp ( const OperatorType &op,
135  double reduction, double absLimit,
136  const ParameterReader &parameter = Parameter::container() )
137  : op_( op ),
138  reduction_( reduction ),
139  absLimit_ ( absLimit ),
140  maxIter_( std::numeric_limits< int >::max() ),
141  verbose_( parameter.getValue< bool >( "fem.solver.verbose", false ) ),
142  iterations_( 0 ),
143  averageCommTime_( 0.0 ),
144  parameter_( parameter )
145  {}
146 
147  void prepare (const DiscreteFunctionType& Arg, DiscreteFunctionType& Dest) const
148  {}
149 
150  void finalize () const
151  {}
152 
153  void printTexInfo(std::ostream& out) const
154  {
155  out << "Solver:"<< SolverCallerType::name() << ", eps = " << reduction_ ;
156  out << "\\\\ \n";
157  }
158 
163  void apply( const DiscreteFunctionType& arg, DiscreteFunctionType& dest ) const
164  {
165  std::pair< int, double > info
166  = SolverCallerType::call( op_, arg, dest, reduction_, absLimit_, maxIter_, verbose_, parameter_ );
167 
168  iterations_ = info.first;
169  averageCommTime_ = info.second;
170  }
171 
172  // return number of iterations
173  int iterations() const
174  {
175  return iterations_;
176  }
177 
179  double averageCommTime() const
180  {
181  return averageCommTime_;
182  }
183 
188  void operator() ( const DiscreteFunctionType& arg, DiscreteFunctionType& dest ) const
189  {
190  apply( arg,dest );
191  }
192 
193  private:
194  const OperatorType &op_;
195  double reduction_;
196  double absLimit_;
197  int maxIter_;
198  bool verbose_ ;
199  mutable int iterations_;
200  mutable double averageCommTime_;
201  ParameterReader parameter_;
202  };
203 
204 
205  // LoopSolverCaller
206  // --------------
207 
208  template< class OperatorImp, class DiscreteFunction >
209  struct LoopSolverCaller
210  : public DefaultSolverCaller< OperatorImp, DiscreteFunction, LoopSolverCaller< OperatorImp, DiscreteFunction > >
211  {
212  typedef LoopSolver< typename DiscreteFunction :: DofStorageType > SolverType;
213 
214  static inline std::string name ()
215  {
216  std::string name = "ISTL LoopSolver";
217  return name;
218  }
219  };
220 
221 
222  // ISTLLoopOp
223  // --------------
224 
227  template< class DF, class Op >
228  struct ISTLLoopOp
229  : public ISTLInverseOp< DF, Op, LoopSolverCaller< Op, DF > >
230  {
231  typedef ISTLInverseOp< DF, Op, LoopSolverCaller< Op, DF > > BaseType;
232  public:
233 
234  template< class ... Args >
235  ISTLLoopOp ( Args && ... args ) : BaseType( std::forward< Args >( args ) ... ) {}
236  };
237 
238 
239  // MINResSolverCaller
240  // ------------------
241 
242  template< class OperatorImp, class DiscreteFunction >
243  struct MINResSolverCaller
244  : public DefaultSolverCaller< OperatorImp, DiscreteFunction, MINResSolverCaller< OperatorImp, DiscreteFunction > >
245  {
246  typedef MINRESSolver< typename DiscreteFunction :: DofStorageType > SolverType;
247 
248  static inline std::string name ()
249  {
250  std::string name = "ISTL MINRESSolver";
251  return name;
252  }
253  };
254 
255 
256  // ISTLMINResOp
257  // --------------
258 
261  template< class DF, class Op >
262  struct ISTLMINResOp
263  : public ISTLInverseOp< DF, Op, MINResSolverCaller< Op, DF > >
264  {
265  typedef ISTLInverseOp< DF, Op, MINResSolverCaller< Op, DF > > BaseType;
266  public:
267  template< class ... Args >
268  ISTLMINResOp ( Args && ... args ) : BaseType( std::forward< Args >( args ) ... ) {}
269  };
270 
271 
272  // BiCGSTABSolverCaller
273  // --------------------
274 
275  template< class OperatorImp, class DiscreteFunction >
276  struct BiCGSTABSolverCaller
277  : public DefaultSolverCaller< OperatorImp, DiscreteFunction, BiCGSTABSolverCaller< OperatorImp, DiscreteFunction > >
278  {
279  typedef BiCGSTABSolver< typename DiscreteFunction :: DofStorageType > SolverType;
280 
281  static inline std::string name ()
282  {
283  std::string name = "ISTL BiCGSTABSolver";
284  return name;
285  }
286  };
287 
288 
289  // ISTLBICGSTABOp
290  // --------------
291 
294  template< class DF, class Op >
295  struct ISTLBICGSTABOp
296  : public ISTLInverseOp< DF, Op, BiCGSTABSolverCaller< Op, DF > >
297  {
298  typedef ISTLInverseOp< DF, Op, BiCGSTABSolverCaller< Op, DF > > BaseType;
299  public:
300  template< class ... Args >
301  ISTLBICGSTABOp ( Args && ... args ) : BaseType( std::forward< Args >( args ) ... ) {}
302  };
303 
304 
305  // GMResSolverCaller
306  // -----------------
307 
308  template< class OperatorImp, class DiscreteFunction >
309  struct GMResSolverCaller
310  {
311 
312  static std::pair< int, double >
313  call ( const OperatorImp &op,
314  const DiscreteFunction &arg, DiscreteFunction &dest,
315  double reduction, double absLimit, int maxIter, bool verbose,
316  const ParameterReader &parameter )
317  {
318  int restart = parameter.getValue< int >( "istl.gmres.restart", 5 );
319  typedef typename OperatorImp :: MatrixAdapterType MatrixAdapterType;
320  MatrixAdapterType matrix = op.systemMatrix().matrixAdapter();
321 
322  typedef typename DiscreteFunction :: DofStorageType BlockVectorType;
323 
324  // verbose only in verbose mode and for rank 0
325  int verb = (verbose && (dest.space().gridPart().comm().rank() == 0)) ? 2 : 0;
326 
327  if( absLimit < std::numeric_limits< double >::max() )
328  {
329  const double residuum = matrix.residuum( arg.blockVector(), dest.blockVector() );
330  reduction = (residuum > 0) ? absLimit/ residuum : 1e-3;
331 
332  if( verbose && (dest.space().gridPart().comm().rank() == 0) )
333  std::cout << "ISTL GMRes-Solver: reduction: " << reduction << ", residuum: " << residuum << ", absolut limit: " << absLimit << std::endl;
334  }
335 
336  RestartedGMResSolver< BlockVectorType >
337  solver( matrix, matrix.scp(), matrix.preconditionAdapter(), reduction, restart, maxIter, verb );
338 
339  // copy right hand side since ISTL is overwriting it
340  BlockVectorType rhs( arg.blockVector() );
341 
342  InverseOperatorResult returnInfo;
343 
344  // call solver
345  solver.apply( dest.blockVector(), rhs, returnInfo );
346 
347  return std::pair< int, double > ( returnInfo.iterations, matrix.averageCommTime() );
348  }
349 
350  static std::string name ()
351  {
352  std::string name = "ISTL GMRes-Solver";
353  return name;
354  }
355  };
356 
357 
358  // ISTLGMResOp
359  // -----------
360 
364  template< class DF, class Op >
365  struct ISTLGMResOp
366  : public ISTLInverseOp< DF, Op, GMResSolverCaller< Op, DF > >
367  {
368  typedef ISTLInverseOp< DF, Op, GMResSolverCaller< Op, DF > > BaseType;
369  public:
370  template< class ... Args >
371  ISTLGMResOp ( Args && ... args ) : BaseType( std::forward< Args >( args ) ... ) {}
372  };
373 
374 
375  // CGSolverCaller
376  // --------------
377 
378  template< class OperatorImp, class DiscreteFunction >
379  struct CGSolverCaller
380  : public DefaultSolverCaller< OperatorImp, DiscreteFunction, CGSolverCaller< OperatorImp, DiscreteFunction > >
381  {
382  typedef CGSolver< typename DiscreteFunction :: DofStorageType > SolverType;
383 
384  static inline std::string name ()
385  {
386  std::string name = "ISTL CGSolver";
387  return name;
388  }
389  };
390 
391 
392  // ISTLCGOp
393  // --------
394 
397  template< class DF, class Op >
398  struct ISTLCGOp
399  : public ISTLInverseOp< DF, Op, CGSolverCaller< Op, DF > >
400  {
401  typedef ISTLInverseOp< DF, Op, CGSolverCaller< Op, DF > > BaseType;
402  public:
403  template< class ... Args >
404  ISTLCGOp ( Args && ... args ) : BaseType( std::forward< Args >( args ) ... ) {}
405  };
406 
407 
408  // SuperLUSolverCaller
409  // -------------------
410 
411  template< class OperatorImp, class DiscreteFunction >
412  struct SuperLUSolverCaller
413  {
414 
415  static std::pair< int, double >
416  call ( const OperatorImp &op,
417  const DiscreteFunction &arg, DiscreteFunction &dest,
418  double reduction, double absLimit, int maxIter, bool verbose )
419  {
420  typedef typename OperatorImp :: MatrixAdapterType MatrixAdapterType;
421  MatrixAdapterType matrix = op.systemMatrix().matrixAdapter();
422 
423  InverseOperatorResult returnInfo;
424 #if HAVE_SUPERLU
425  // create solver
426  typedef typename MatrixAdapterType :: MatrixType MatrixType;
427  typedef typename MatrixType :: BaseType ISTLMatrixType;
428  SuperLU< ISTLMatrixType > solver( matrix.getmat(), verbose );
429  // solve the system
430  solver.apply( dest.blockVector(), arg.blockVector(), returnInfo );
431 #else
432  DUNE_THROW(NotImplemented,"SuperLU solver not found in configure, please re-configure");
433 #endif
434 
435  // get information
436  std::pair< int, double > p( returnInfo.iterations, matrix.averageCommTime() );
437  return p;
438  }
439 
440  static std::string name ()
441  {
442  std::string name = "ISTL SuperLU";
443  return name;
444  }
445  };
446 
447 
448  // ISTLSuperLUOp
449  // --------------
450 
458  template< class DF, class Op >
459  struct ISTLSuperLU
460  : public ISTLInverseOp< DF, Op, SuperLUSolverCaller< Op, DF > >
461  {
462  typedef ISTLInverseOp< DF, Op, SuperLUSolverCaller< Op, DF > > BaseType;
463  public:
464  template< class ... Args >
465  ISTLSuperLU ( Args && ... args ) : BaseType( std::forward< Args >( args ) ... ) {}
466  };
467 
468 
470 
471  } // namespace Fem
472 
473 } // namespace Dune
474 
475 #endif // #if HAVE_DUNE_ISTL
476 
477 #endif // #ifndef DUNE_FEM_ISTLSOLVERS_HH
BasicParameterReader< std::function< const std::string *(const std::string &, const std::string *) > > ParameterReader
Definition: reader.hh:264
static constexpr T max(T a)
Definition: utility.hh:65
static double max(const Double &v, const double p)
Definition: double.hh:387
Definition: coordinate.hh:4
static ParameterContainer & container()
Definition: io/parameter.hh:190
STL namespace.