1#ifndef DUNE_FEM_SOLVER_INVERSEOPERATORS_HH 
    2#define DUNE_FEM_SOLVER_INVERSEOPERATORS_HH 
    4#include <dune/fem/function/adaptivefunction.hh> 
    5#include <dune/fem/operator/common/operator.hh> 
    6#include <dune/fem/io/parameter.hh> 
    7#include <dune/fem/solver/parameter.hh> 
    9#include <dune/fem/solver/cginverseoperator.hh> 
   10#include <dune/fem/solver/fempreconditioning.hh> 
   12#include <dune/fem/solver/linear/gmres.hh> 
   13#include <dune/fem/solver/linear/bicgstab.hh> 
   14#include <dune/fem/solver/linear/cg.hh> 
   15#include <dune/fem/solver/inverseoperatorinterface.hh> 
   17#include <dune/fem/misc/mpimanager.hh> 
   28    template< 
class DiscreteFunction, 
int method = -1 >
 
   29    class KrylovInverseOperator;
 
   31    template< 
class DiscreteFunction, 
int method >
 
   32    struct KrylovInverseOperatorTraits
 
   36      typedef OperatorType  PreconditionerType;
 
   38      typedef OperatorType AssembledOperatorType;
 
   39      typedef DiscreteFunction SolverDiscreteFunctionType ;
 
   42      typedef SolverParameter SolverParameterType;
 
   46    template< 
class DiscreteFunction, 
int method >
 
   47    class KrylovInverseOperator
 
   48    : 
public InverseOperatorInterface< KrylovInverseOperatorTraits< DiscreteFunction, method > >
 
   50      typedef KrylovInverseOperatorTraits< DiscreteFunction, method > Traits;
 
   51      typedef InverseOperatorInterface< Traits > BaseType;
 
   53      friend class InverseOperatorInterface< Traits >;
 
   55      typedef typename BaseType::DomainFunctionType     DomainFunctionType;
 
   56      typedef typename BaseType::RangeFunctionType      RangeFunctionType;
 
   57      typedef typename BaseType::OperatorType           OperatorType;
 
   58      typedef typename BaseType::PreconditionerType     PreconditionerType;
 
   59      typedef typename BaseType::AssembledOperatorType  AssembledOperatorType;
 
   61      using BaseType :: bind;
 
   62      using BaseType :: unbind;
 
   63      using BaseType :: setMaxLinearIterations;
 
   64      using BaseType :: setMaxIterations;
 
   67      KrylovInverseOperator ( 
const OperatorType &op, 
const SolverParameter ¶meter = SolverParameter(Parameter::container()) )
 
   68        : KrylovInverseOperator( parameter )
 
   73      KrylovInverseOperator ( 
const OperatorType &op, 
const PreconditionerType& preconditioner,
 
   74                              const SolverParameter ¶meter = SolverParameter(Parameter::container()) )
 
   75        : KrylovInverseOperator( op, &preconditioner, parameter )
 
   79      KrylovInverseOperator ( 
const SolverParameter ¶meter = SolverParameter(Parameter::container()) )
 
   80      : BaseType( parameter ),
 
   82        verbose_( parameter.verbose() ),
 
   83        method_( method < 0 ? parameter.solverMethod( supportedSolverMethods() ) : method ),
 
   84        precondMethod_( parameter.preconditionMethod( supportedPreconditionMethods() ) )
 
   89      template <
class Operator>
 
   90      void bind ( 
const Operator &op )
 
   92        if( precondMethod_ && std::is_base_of< AssembledOperator< DomainFunctionType, DomainFunctionType >, Operator > :: value )
 
   94          createPreconditioner( op );
 
   98          BaseType::bind( op, *precondObj_ );
 
  100          BaseType::bind( op );
 
  103      static std::vector< int > supportedSolverMethods() {
 
  104        return std::vector< int > ({ SolverParameter::gmres, 
 
  106                                     SolverParameter::bicgstab });
 
  109      static std::vector< int > supportedPreconditionMethods() {
 
  111                                     SolverParameter::sor,
 
  112                                     SolverParameter::ssor,
 
  113                                     SolverParameter::gauss_seidel,
 
  114                                     SolverParameter::jacobi } );
 
  118      int apply( 
const DomainFunctionType &u, RangeFunctionType &w )
 const 
  120        std::ostream* os = 
nullptr;
 
  126          if( method_ == SolverParameter::gmres )
 
  127            std::cout << 
"Fem::GMRES";
 
  128          else if ( method_ == SolverParameter::bicgstab )
 
  129            std::cout << 
"Fem::BiCGstab";
 
  130          else if ( method_ == SolverParameter::cg )
 
  131            std::cout << 
"Fem::CG";
 
  133          std::cout << 
" preconditioning="<< SolverParameter::preconditionMethodTable( precondMethod_ ) << std::endl;
 
  138        if( method_ == SolverParameter::gmres )
 
  142            const int extra = ( preconditioner_ ) ? 2 : 1 ;
 
  143            v_.reserve( parameter_->gmresRestart()+extra );
 
  144            for( 
int i=0; i<=parameter_->gmresRestart(); ++i )
 
  146              v_.emplace_back( DiscreteFunction( 
"GMRes::v", u.space() ) );
 
  148            if( preconditioner_ )
 
  149              v_.emplace_back( DiscreteFunction( 
"GMRes::z", u.space() ) );
 
  153          numIter = LinearSolver::gmres( *operator_, preconditioner_,
 
  154                                         v_, w, u, parameter_->gmresRestart(),
 
  155                                         parameter_->tolerance(), parameter_->maxIterations(),
 
  156                                         parameter_->errorMeasure(), os );
 
  158        else if( method_ == SolverParameter::bicgstab )
 
  162            v_.emplace_back( DomainFunctionType( 
"BiCGStab::r",   u.space() ) );
 
  163            v_.emplace_back( DomainFunctionType( 
"BiCGStab::r*",  u.space() ) );
 
  164            v_.emplace_back( DomainFunctionType( 
"BiCGStab::p",   u.space() ) );
 
  165            v_.emplace_back( DomainFunctionType( 
"BiCGStab::s",   u.space() ) );
 
  166            v_.emplace_back( DomainFunctionType( 
"BiCGStab::tmp", u.space() ) );
 
  167            if( preconditioner_ )
 
  168              v_.emplace_back( DomainFunctionType( 
"BiCGStab::z", u.space() ) );
 
  172          numIter = LinearSolver::bicgstab( *operator_, preconditioner_,
 
  174                                            parameter_->tolerance(), parameter_->maxIterations(),
 
  175                                            parameter_->errorMeasure(), os );
 
  177        else if( method_ == SolverParameter::cg )
 
  181            v_.emplace_back( DomainFunctionType( 
"CG::h",  u.space() ) );
 
  182            v_.emplace_back( DomainFunctionType( 
"CG::r",  u.space() ) );
 
  183            v_.emplace_back( DomainFunctionType( 
"CG::p",  u.space() ) );
 
  185            if( preconditioner_ )
 
  187              v_.emplace_back( DomainFunctionType( 
"CG::s", u.space() ) );
 
  188              v_.emplace_back( DomainFunctionType( 
"CG::q", u.space() ) );
 
  193          numIter = LinearSolver::cg( *operator_, preconditioner_,
 
  195                                      parameter_->tolerance(), parameter_->maxIterations(),
 
  196                                      parameter_->errorMeasure(), os );
 
  200          DUNE_THROW(InvalidStateException,
"KrylovInverseOperator: invalid method " << method_ );
 
  206      template <
class LinearOperator>
 
  207      KrylovInverseOperator ( 
const LinearOperator &op,
 
  208                              const PreconditionerType *preconditioner,
 
  209                              const SolverParameter ¶meter = SolverParameter(Parameter::container()) )
 
  210      : KrylovInverseOperator( parameter )
 
  216      template <
class LinearOperator>
 
  217      void createPreconditioner( 
const LinearOperator &op )
 
  219        if( precondMethod_ > 0 && std::is_base_of< AssembledOperator< DomainFunctionType, DomainFunctionType >, LinearOperator > :: value )
 
  221          const int n = parameter_->preconditionerIteration();
 
  222          const double w = parameter_->relaxation();
 
  224          if( precondMethod_ == SolverParameter::jacobi )
 
  227            precondObj_.reset( 
new FemJacobiPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
 
  229          else if( precondMethod_ == SolverParameter::gauss_seidel )
 
  232            precondObj_.reset( 
new FemGaussSeidelPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
 
  234          else if( precondMethod_ == SolverParameter::sor )
 
  237            precondObj_.reset( 
new FemSORPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
 
  239          else if( precondMethod_ == SolverParameter::ssor )
 
  242            precondObj_.reset( 
new FemSSORPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
 
  248            preconditioner_ = precondObj_.operator->();
 
  253      using BaseType :: operator_;
 
  254      using BaseType :: preconditioner_;
 
  256      using BaseType :: parameter_;
 
  257      using BaseType :: iterations_;
 
  259      std::unique_ptr< PreconditionerType > precondObj_;
 
  261      mutable std::vector< DomainFunctionType > v_;
 
  266      const int precondMethod_;
 
  273    template< 
class DiscreteFunction >
 
  274    using CgInverseOperator = KrylovInverseOperator< DiscreteFunction, SolverParameter :: cg >;
 
  280    template< 
class DiscreteFunction >
 
  281    using BicgstabInverseOperator = KrylovInverseOperator< DiscreteFunction, SolverParameter :: bicgstab >;
 
  287    template< 
class DiscreteFunction >
 
  288    using GmresInverseOperator = KrylovInverseOperator< DiscreteFunction, SolverParameter :: gmres >;
 
  294    template< 
class DiscreteFunction >
 
  295    using ParDGGeneralizedMinResInverseOperator = GmresInverseOperator< DiscreteFunction >;
 
  300    template< 
class DiscreteFunction >
 
  301    using ParDGBiCGStabInverseOperator = BicgstabInverseOperator< DiscreteFunction >;
 
  303    template <
class DiscreteFunctionType, 
class OpType >
 
  304    using OEMCGOp = CgInverseOperator< DiscreteFunctionType >;
 
  306    template <
class DiscreteFunctionType, 
class OpType >
 
  307    using OEMBICGSTABOp = BicgstabInverseOperator< DiscreteFunctionType >;
 
  309    template <
class DiscreteFunctionType, 
class OpType >
 
  310    using OEMBICGSQOp = BicgstabInverseOperator< DiscreteFunctionType >;
 
  312    template <
class DiscreteFunctionType, 
class OpType >
 
  313    using OEMGMRESOp = GmresInverseOperator< DiscreteFunctionType >;
 
  315    template <
class DiscreteFunctionType, 
class OpType >
 
  316    using GMRESOp = GmresInverseOperator< DiscreteFunctionType >;
 
Inverse operator base on CG method. Uses a runtime parameter fem.preconditioning which enables diagon...
Definition: cginverseoperator.hh:408
 
static bool verbose()
obtain the cached value for fem.verbose with default verbosity level 2
Definition: parameter.hh:466
 
forward declaration
Definition: discretefunction.hh:51
 
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
 
constexpr GeometryType none(unsigned int dim)
Returns a GeometryType representing a singular of dimension dim.
Definition: type.hh:471
 
Dune namespace.
Definition: alignedallocator.hh:13