dune-fem  2.4.1-rc
cginverseoperator.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_CGINVERSEOPERATOR_HH
2 #define DUNE_FEM_CGINVERSEOPERATOR_HH
3 
4 #include <dune/common/typetraits.hh>
5 
9 
11 
12 namespace Dune
13 {
14 
15  namespace Fem
16  {
17 
18  // ConjugateGradientSolver
19  // -----------------------
20 
27  template< class Operator>
29  {
31 
32  public:
35 
40  typedef typename Dune::FieldTraits< RangeFieldType >::real_type RealType;
41 
46 
49 
50 
51  private:
52  static_assert( (Conversion< DomainFunctionType, RangeFunctionType >::sameType),
53  "DomainFunctionType must equal RangeFunctionType." );
54 
55  public:
62  ConjugateGradientSolver ( const RealType &epsilon,
63  unsigned int maxIterations,
64  bool verbose,
65  const ParameterReader &parameter = Parameter::container() )
66  : epsilon_( epsilon ),
67  maxIterations_( maxIterations ),
68  verbose_( verbose ),
69  averageCommTime_( 0.0 ),
70  realCount_( 0 )
71 
72  {}
73 
79  ConjugateGradientSolver ( RealType epsilon,
80  unsigned int maxIterations,
81  const ParameterReader &parameter = Parameter::container() )
82  : epsilon_( epsilon ),
83  maxIterations_( maxIterations ),
84  verbose_( parameter.getValue< bool >( "fem.solver.verbose", false ) ),
85  averageCommTime_( 0.0 ),
86  realCount_( 0 )
87  {}
88 
89  ConjugateGradientSolver ( const ThisType & )=delete;
90 
102  void solve ( const OperatorType &op, const RangeFunctionType &b, DomainFunctionType &x ) const;
103 
116  void solve ( const OperatorType &op, const PreconditionerType &p,
117  const RangeFunctionType &b, DomainFunctionType &x ) const;
118 
120  unsigned int iterations () const
121  {
122  return realCount_;
123  }
124 
126  double averageCommTime() const
127  {
128  return averageCommTime_;
129  }
130 
131  protected:
132  const RealType epsilon_;
133  const unsigned int maxIterations_;
134  const bool verbose_;
135  mutable double averageCommTime_;
136  mutable unsigned int realCount_;
137  };
138 
139 
140  namespace Solver
141  {
142  // CGInverseOperator
143  // -----------------
144 
150  template< class DiscreteFunction >
152  : public Fem::Operator< DiscreteFunction, DiscreteFunction >
153  {
155 
156  public:
159 
162 
164  typedef typename Dune::FieldTraits< RangeFieldType >::real_type RealType;
165 
166  private:
168 
169  public:
178  CGInverseOperator ( const OperatorType &op,
179  RealType redEps, RealType absLimit,
180  unsigned int maxIter, bool verbose,
181  const ParameterReader &parameter = Parameter::container() )
182  : operator_( op ),
183  preconditioner_ ( 0 ),
184  solver_( absLimit, maxIter, verbose, parameter ),
185  parameter_( parameter )
186  {}
187 
188 
196  CGInverseOperator ( const OperatorType &op,
197  RealType redEps, RealType absLimit,
198  unsigned int maxIter,
199  const ParameterReader &parameter = Parameter::container() )
200  : operator_( op ),
201  preconditioner_ ( 0 ),
202  solver_( absLimit, maxIter, parameter ),
203  parameter_( parameter )
204  {}
205 
206  CGInverseOperator ( const OperatorType &op,
207  RealType redEps, RealType absLimit,
208  const ParameterReader &parameter = Parameter::container() )
209  : operator_( op ),
210  preconditioner_ ( 0 ),
211  solver_( absLimit, std::numeric_limits< unsigned int >::max(), parameter ),
212  parameter_( parameter )
213  {}
214 
223  CGInverseOperator ( const OperatorType &op,
224  const PreconditionerType &precond,
225  RealType redEps, RealType absLimit,
226  const ParameterReader &parameter = Parameter::container() )
227  : operator_( op ),
228  preconditioner_( &precond ),
229  solver_( absLimit, std::numeric_limits< unsigned int >::max(), parameter ),
230  parameter_( parameter )
231  {}
232 
233  CGInverseOperator ( const OperatorType &op,
234  const PreconditionerType &precond,
235  RealType redEps, RealType absLimit,
236  unsigned int maxIter,
237  const ParameterReader &parameter = Parameter::container() )
238  : operator_( op ),
239  preconditioner_( &precond ),
240  solver_( absLimit, maxIter, parameter ),
241  parameter_( parameter )
242  {}
243 
252  virtual void operator()( const DomainFunctionType &arg, RangeFunctionType &dest ) const
253  {
254  prepare();
255  apply(arg,dest);
256  finalize();
257  }
258 
259  template<typename... A>
260  inline void prepare(A... ) const
261  {}
262 
263  inline void finalize() const
264  {}
265 
274  virtual void apply( const DomainFunctionType &arg, RangeFunctionType &dest ) const
275  {
276  if(preconditioner_)
277  solver_.solve( operator_, *preconditioner_, arg, dest );
278  else
279  solver_.solve(operator_,arg,dest);
280  }
281 
283  unsigned int iterations () const
284  {
285  return solver_.iterations();
286  }
287 
289  double averageCommTime() const
290  {
291  return solver_.averageCommTime();
292  }
293 
294  protected:
295  const OperatorType &operator_;
296  const PreconditionerType *preconditioner_;
297  SolverType solver_;
299  };
300  }
301 
302  // CGInverseOperator
303  // -----------------
304 
312  template< class DiscreteFunction,
315  : public Fem::Solver::CGInverseOperator< DiscreteFunction >
316  {
318 
319  public:
322 
323  typedef DomainFunctionType DestinationType;
324 
326  typedef Op OperatorType;
327 
329  typedef typename Dune::FieldTraits< RangeFieldType >::real_type RealType;
330 
331  // Preconditioner is to approximate op^-1 !
333 
342  template <class LinearOperator>
344  RealType redEps, RealType absLimit,
345  unsigned int maxIter, bool verbose,
346  const ParameterReader &parameter = Parameter::container() )
347  : BaseType( op, redEps, absLimit, maxIter, verbose, parameter ),
348  precondObj_( 0 )
349  {
350  checkPreconditioning( op );
351  }
352 
360  template <class LinearOperator>
362  RealType redEps, RealType absLimit,
363  unsigned int maxIter,
364  const ParameterReader &parameter = Parameter::container() )
365  : BaseType( op, redEps, absLimit, maxIter, parameter ),
366  precondObj_( 0 )
367  {
368  checkPreconditioning( op );
369  }
370 
371  template <class LinearOperator>
373  RealType redEps, RealType absLimit,
374  const ParameterReader &parameter = Parameter::container() )
375  : BaseType( op, redEps, absLimit, std::numeric_limits< unsigned int >::max(), parameter ),
376  precondObj_( 0 )
377  {
378  checkPreconditioning( op );
379  }
380 
389  CGInverseOperator ( const OperatorType &op,
390  const PreconditioningType &precond,
391  RealType redEps, RealType absLimit,
392  unsigned int maxIter,
393  const ParameterReader &parameter = Parameter::container() )
394  : BaseType( op, precond, redEps, absLimit, maxIter, parameter ),
395  precondObj_( 0 )
396  {}
397 
398  CGInverseOperator ( const OperatorType &op,
399  const PreconditioningType &precond,
400  RealType redEps, RealType absLimit,
401  const ParameterReader &parameter = Parameter::container() )
402  : BaseType( op, precond, redEps, absLimit, std::numeric_limits< unsigned int >::max(), parameter ),
403  precondObj_( 0 )
404  {}
405 
408  {
409  if( precondObj_ )
410  delete precondObj_;
411  }
412 
413  protected:
414  template< class LinearOperator >
415  void checkPreconditioning( const LinearOperator &linearOp )
416  {
417  const bool preconditioning = parameter_.template getValue< bool >( "fem.preconditioning", false );
418  if( preconditioning && IsBaseOf< AssembledOperator< DomainFunctionType, DomainFunctionType > ,LinearOperator > :: value )
419  {
420  // create diagonal preconditioner
422  preconditioner_ = precondObj_;
423  }
424  }
425 
426  using BaseType::preconditioner_;
427  using BaseType::parameter_;
428  PreconditioningType *precondObj_;
429  };
430 
431  // Implementation of ConjugateGradientSolver
432  // -----------------------------------------
433 
434  template< class Operator >
436  ::solve ( const OperatorType &op, const RangeFunctionType &b, DomainFunctionType &x ) const
437  {
438  const bool verbose = (verbose_ && (b.space().gridPart().comm().rank() == 0));
439 
440  const RealType tolerance = (epsilon_ * epsilon_) * b.normSquaredDofs( );
441 
442  averageCommTime_ = 0.0;
443 
444  RangeFunctionType h( b );
445  op( x, h );
446 
447  RangeFunctionType r( h );
448  r -= b;
449 
450  RangeFunctionType p( b );
451  p -= h;
452 
453  RealType prevResiduum = 0;
454  RealType residuum = r.normSquaredDofs( );
455 
456  for( realCount_ = 0; (residuum > tolerance) && (realCount_ < maxIterations_); ++realCount_ )
457  {
458  if( realCount_ > 0 )
459  {
460  assert( residuum/prevResiduum == residuum/prevResiduum );
461  p *= (residuum / prevResiduum);
462  p -= r;
463  }
464 
465  op( p, h );
466 
467  RangeFieldType pdoth = p.scalarProductDofs( h );
468  const RangeFieldType alpha = residuum / pdoth;
469  assert( alpha == alpha );
470  x.axpy( alpha, p );
471  r.axpy( alpha, h );
472 
473  prevResiduum = residuum;
474  residuum = r.normSquaredDofs( );
475 
476  double exchangeTime = h.space().communicator().exchangeTime();
477  if( verbose )
478  {
479  std::cerr << "CG-Iteration: " << realCount_ << ", sqr(Residuum): " << residuum << std::endl;
480  // only for parallel apps
481  if( b.space().gridPart().comm().size() > 1 )
482  std::cerr << "Communication needed: " << exchangeTime << " s" << std::endl;
483  }
484 
485  averageCommTime_ += exchangeTime;
486  }
487  }
488 
489 
490  template< class Operator >
492  ::solve ( const OperatorType &op, const PreconditionerType &precond, const RangeFunctionType &b, DomainFunctionType &x ) const
493  {
494  const bool verbose = (verbose_ && (b.space().gridPart().comm().rank() == 0));
495 
496  const RealType tolerance = (epsilon_ * epsilon_) * b.normSquaredDofs( );
497 
498  averageCommTime_ = 0.0;
499 
500  RangeFunctionType h( b );
501  //h=Ax
502  op( x, h );
503 
504  //r=Ax-b
505  RangeFunctionType r( h );
506  r -= b;
507 
508  //p=b-A*x <= r_0 Deufelhard
509  RangeFunctionType p( b );
510  p -= h;
511 
512  //q=B*p <=q Deuf
513  RangeFunctionType q ( b );
514  precond(p,q);
515 
516  RangeFunctionType s (q);
517 
518  RangeFieldType prevResiduum = 0; // note that these will be real_type but require scalar product evaluation
519  RangeFieldType residuum = p.scalarProductDofs( q );//<p,Bp>
520 
521  for( realCount_ = 0; (std::real(residuum) > tolerance) && (realCount_ < maxIterations_); ++realCount_ )
522  {
523  if( realCount_ > 0 )
524  {
525  assert( residuum/prevResiduum == residuum/prevResiduum );
526  const RangeFieldType beta=residuum/prevResiduum;
527  q*=beta;
528  q+=(s);
529  }
530 
531  op( q, h );
532 
533  RangeFieldType qdoth = q.scalarProductDofs( h );
534  const RangeFieldType alpha = residuum / qdoth;//<p,Bp>/<q,Aq>
535  assert( alpha == alpha );
536  x.axpy( alpha, q );
537 
538  p.axpy( -alpha, h );//r_k
539 
540  precond(p,s); //B*r_k
541 
542  prevResiduum = residuum;//<rk-1,B*rk-1>
543 
544  residuum = p.scalarProductDofs( s );//<rk,B*rk>
545 
546  double exchangeTime = h.space().communicator().exchangeTime();
547  if( verbose )
548  {
549  std::cerr << "CG-Iteration: " << realCount_ << ", Residuum: " << residuum << std::endl;
550  // only for parallel apps
551  if( b.space().gridPart().comm().size() > 1 )
552  std::cerr << "Communication needed: " << exchangeTime << " s" << std::endl;
553  }
554 
555  averageCommTime_ += exchangeTime;
556  }
557  }
558 
559  } // namespace Fem
560 
561 } // namespace Dune
562 
563 #endif // #ifndef DUNE_FEM_CGINVERSEOPERATOR_HH
RangeFunction RangeFunctionType
type of discrete function in the operator&#39;s range
Definition: operator.hh:30
Inverse operator base on CG method. This is the base class for the cg solver and does not imvolve any...
Definition: cginverseoperator.hh:151
const PreconditionerType * preconditioner_
Definition: cginverseoperator.hh:296
ConjugateGradientSolver(RealType epsilon, unsigned int maxIterations, const ParameterReader &parameter=Parameter::container())
constructor
Definition: cginverseoperator.hh:79
CGInverseOperator(const LinearOperator &op, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition: cginverseoperator.hh:372
CGInverseOperator(const OperatorType &op, const PreconditioningType &precond, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition: cginverseoperator.hh:389
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition: cginverseoperator.hh:329
unsigned int iterations() const
number of iterations needed for last solve
Definition: cginverseoperator.hh:120
void solve(const OperatorType &op, const RangeFunctionType &b, DomainFunctionType &x) const
solve
Definition: cginverseoperator.hh:436
OperatorType::RangeFieldType RangeFieldType
Definition: cginverseoperator.hh:328
linear solver using the CG algorithm
Definition: cginverseoperator.hh:28
CGInverseOperator(const OperatorType &op, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition: cginverseoperator.hh:206
double averageCommTime_
Definition: cginverseoperator.hh:135
Fem::Operator< RangeFunctionType, DomainFunctionType > PreconditioningType
Definition: cginverseoperator.hh:332
unsigned int iterations() const
number of iterations needed for last solve
Definition: cginverseoperator.hh:283
ParameterReader parameter_
Definition: cginverseoperator.hh:298
static double max(const Double &v, const double p)
Definition: double.hh:387
virtual void apply(const DomainFunctionType &arg, RangeFunctionType &dest) const
application operator
Definition: cginverseoperator.hh:274
void prepare(A...) const
Definition: cginverseoperator.hh:260
void checkPreconditioning(const LinearOperator &linearOp)
Definition: cginverseoperator.hh:415
double averageCommTime() const
return average communication time during last solve
Definition: cginverseoperator.hh:289
CGInverseOperator(const OperatorType &op, const PreconditionerType &precond, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
Definition: cginverseoperator.hh:233
BaseType::DomainFunctionType DomainFunctionType
Definition: cginverseoperator.hh:320
Fem::Operator< RangeFunctionType, DomainFunctionType > PreconditionerType
type of the preconditioner, maps from the range of the operator (the dual space) in it&#39;s domain ...
Definition: cginverseoperator.hh:48
unsigned int realCount_
Definition: cginverseoperator.hh:136
abstract operator
Definition: operator.hh:25
const RealType epsilon_
Definition: cginverseoperator.hh:132
double averageCommTime() const
return average communication time during last solve
Definition: cginverseoperator.hh:126
CGInverseOperator(const OperatorType &op, RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition: cginverseoperator.hh:178
Op OperatorType
type of operator
Definition: cginverseoperator.hh:326
OperatorType::DomainFieldType DomainFieldType
field type of the operator&#39;s domain vectors
Definition: cginverseoperator.hh:37
BaseType::DomainFunctionType DomainFunctionType
Definition: cginverseoperator.hh:157
Definition: coordinate.hh:4
~CGInverseOperator()
destructor
Definition: cginverseoperator.hh:407
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition: cginverseoperator.hh:164
Fem::Operator< DomainFunctionType, RangeFunctionType > OperatorType
Definition: cginverseoperator.hh:160
CGInverseOperator(const OperatorType &op, const PreconditionerType &precond, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition: cginverseoperator.hh:223
static ParameterContainer & container()
Definition: io/parameter.hh:190
STL namespace.
virtual void operator()(const DomainFunctionType &arg, RangeFunctionType &dest) const
application operator
Definition: cginverseoperator.hh:252
Fem::Operator< RangeFunctionType, DomainFunctionType > PreconditionerType
Definition: cginverseoperator.hh:161
DomainFunction::RangeFieldType DomainFieldType
field type of the operator&#39;s domain
Definition: operator.hh:33
const unsigned int maxIterations_
Definition: cginverseoperator.hh:133
RangeFunction::RangeFieldType RangeFieldType
field type of the operator&#39;s range
Definition: operator.hh:35
abstract affine-linear operator
Definition: operator.hh:70
CGInverseOperator(const LinearOperator &op, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition: cginverseoperator.hh:361
Inverse operator base on CG method. Uses a runtime parameter fem.preconditioning which enables diagon...
Definition: cginverseoperator.hh:314
double real(const std::complex< Double > &x)
Definition: double.hh:890
OperatorType::RangeFieldType RangeFieldType
field type of the operator&#39;s range vectors
Definition: cginverseoperator.hh:39
BaseType::RangeFunctionType RangeFunctionType
Definition: cginverseoperator.hh:158
CGInverseOperator(const OperatorType &op, const PreconditioningType &precond, RealType redEps, RealType absLimit, const ParameterReader &parameter=Parameter::container())
Definition: cginverseoperator.hh:398
OperatorType::RangeFieldType RangeFieldType
Definition: cginverseoperator.hh:163
abstract matrix operator
Definition: operator.hh:106
DomainFunctionType DestinationType
Definition: cginverseoperator.hh:323
Operator OperatorType
type of the operators to invert
Definition: cginverseoperator.hh:34
BaseType::RangeFunctionType RangeFunctionType
Definition: cginverseoperator.hh:321
OperatorType::RangeFunctionType RangeFunctionType
type of the operator&#39;s range vectors
Definition: cginverseoperator.hh:45
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition: cginverseoperator.hh:40
Precondtioner, multiplies with inverse of the diagonal works with.
Definition: diagonalpreconditioner.hh:148
PreconditioningType * precondObj_
Definition: cginverseoperator.hh:428
void finalize() const
Definition: cginverseoperator.hh:263
OperatorType::DomainFunctionType DomainFunctionType
type of the operator&#39;s domain vectors
Definition: cginverseoperator.hh:43
CGInverseOperator(const LinearOperator &op, RealType redEps, RealType absLimit, unsigned int maxIter, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition: cginverseoperator.hh:343
SolverType solver_
Definition: cginverseoperator.hh:297
ConjugateGradientSolver(const RealType &epsilon, unsigned int maxIterations, bool verbose, const ParameterReader &parameter=Parameter::container())
constructor
Definition: cginverseoperator.hh:62
const OperatorType & operator_
Definition: cginverseoperator.hh:295
DomainFunction DomainFunctionType
type of discrete function in the operator&#39;s domain
Definition: operator.hh:28
CGInverseOperator(const OperatorType &op, RealType redEps, RealType absLimit, unsigned int maxIter, const ParameterReader &parameter=Parameter::container())
constructor of CGInverseOperator
Definition: cginverseoperator.hh:196
const bool verbose_
Definition: cginverseoperator.hh:134