1#ifndef DUNE_FEM_SOLVER_ISTLINVERSEOPERATORS_HH 
    2#define DUNE_FEM_SOLVER_ISTLINVERSEOPERATORS_HH 
    4#include <dune/fem/function/blockvectorfunction.hh> 
    5#include <dune/fem/function/common/scalarproducts.hh> 
    6#include <dune/fem/operator/common/operator.hh> 
    7#include <dune/fem/io/parameter.hh> 
    8#include <dune/fem/misc/mpimanager.hh> 
   10#include <dune/fem/solver/parameter.hh> 
   11#include <dune/fem/solver/inverseoperatorinterface.hh> 
   16#include <dune/fem/operator/linear/istladapter.hh> 
   17#include <dune/fem/operator/linear/istloperator.hh> 
   21#include <dune/istl/preconditioner.hh> 
   30    template< 
class Preconditioner >
 
   31    class ISTLPreconditionAdapter
 
   32     : 
public Dune::Preconditioner< typename Preconditioner::RangeFunctionType::DofStorageType, typename Preconditioner::DomainFunctionType::DofStorageType >
 
   34      typedef ISTLPreconditionAdapter< Preconditioner > ThisType;
 
   37      typedef typename Preconditioner::DomainFunctionType DomainFunctionType;
 
   38      typedef typename Preconditioner::RangeFunctionType  RangeFunctionType;
 
   41      typedef typename BaseType::domain_type domain_type;
 
   42      typedef typename BaseType::range_type  range_type;
 
   43      typedef typename BaseType::field_type  field_type;
 
   45      typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainFunctionSpaceType;
 
   46      typedef typename RangeFunctionType::DiscreteFunctionSpaceType  RangeFunctionSpaceType;
 
   48      ISTLPreconditionAdapter ( 
const Preconditioner *precon, 
const DomainFunctionSpaceType &domainSpace, 
const RangeFunctionSpaceType &rangeSpace )
 
   50        domainSpace_( domainSpace ),
 
   51        rangeSpace_( rangeSpace )
 
   55      virtual void pre ( domain_type &x, range_type &y )
 override {}
 
   56      virtual void post ( domain_type &x )
 override {}
 
   58      virtual void apply ( domain_type &x, 
const range_type &y )
 override 
   69          RangeFunctionType px( 
"ISTLPreconditionAdapter::apply::x", rangeSpace_, x );
 
   70          DomainFunctionType py( 
"ISTLPreconditionAdapter::apply::y", domainSpace_, y );
 
   79      const Preconditioner *precon_;
 
   80      const DomainFunctionSpaceType &domainSpace_;
 
   81      const RangeFunctionSpaceType &rangeSpace_;
 
   85    template< 
class BlockVector >
 
   86    struct ISTLSolverReduction
 
   88      ISTLSolverReduction ( std::shared_ptr< ISTLSolverParameter > parameter )
 
   89        : parameter_(  parameter )
 
   94                          const BlockVector &rhs, 
const BlockVector &x )
 const 
   97        if( parameter_->errorMeasure() == 0)
 
   99          BlockVector residuum( rhs );
 
  101          const double res = scp.
norm( residuum );
 
  102          return (res > 0 ? parameter_->tolerance() / res : 1e-3);
 
  105          return parameter_->tolerance();
 
  109      std::shared_ptr<ISTLSolverParameter> parameter_;
 
  113    struct ISTLInverseOperatorMethods
 
  115      static std::vector< int > supportedSolverMethods() {
 
  116        return std::vector< int > ({
 
  117                                     SolverParameter::gmres, 
 
  119                                     SolverParameter::bicgstab,
 
  120                                     SolverParameter::minres,
 
  121                                     SolverParameter::gradient,
 
  122                                     SolverParameter::loop,
 
  123                                     SolverParameter::superlu
 
  128    template< 
int method,
 
  130              class Reduction = ISTLSolverReduction< X > >
 
  131    struct ISTLSolverAdapter
 
  133      typedef Reduction ReductionType;
 
  135      typedef X domain_type;
 
  136      typedef X range_type;
 
  138      ISTLSolverAdapter ( 
const ReductionType &reduction, std::shared_ptr<ISTLSolverParameter> parameter )
 
  139        : reduction_( reduction ),
 
  140          method_( method < 0 ? parameter->solverMethod( ISTLInverseOperatorMethods::supportedSolverMethods() ) : method ),
 
  141          parameter_( parameter )
 
  144      template<
class Op, 
class ScP, 
class PC >
 
  145      void operator () ( Op& op, ScP &scp, PC &pc,
 
  146                         range_type &rhs, domain_type &x,
 
  149        int verbosity = (
Parameter::verbose( Parameter::solverStatistics ) && parameter_->verbose()) ? 2 : 0;
 
  154        if( method_ == SolverParameter::cg )
 
  157          SolverType solver( op, scp, pc, reduction_( op, scp, rhs, x ), maxIterations, verbosity );
 
  158          solver.apply( x, rhs, result );
 
  161        else if( method_ == SolverParameter::bicgstab )
 
  164          SolverType solver( op, scp, pc, reduction_( op, scp, rhs, x ), maxIterations, verbosity );
 
  165          solver.apply( x, rhs, result );
 
  168        else if( method_ == SolverParameter::gmres )
 
  171          SolverType solver( op, scp, pc, reduction_( op, scp, rhs, x ), parameter_->gmresRestart(), maxIterations, verbosity );
 
  172          solver.apply( x, rhs, result );
 
  175        else if( method_ == SolverParameter::minres )
 
  178          SolverType solver( op, scp, pc, reduction_( op, scp, rhs, x ), maxIterations, verbosity );
 
  179          solver.apply( x, rhs, result );
 
  181        else if( method_ == SolverParameter::gradient )
 
  184          SolverType solver( op, scp, pc, reduction_( op, scp, rhs, x ), maxIterations, verbosity );
 
  185          solver.apply( x, rhs, result );
 
  188        else if( method_ == SolverParameter::loop )
 
  191          SolverType solver( op, scp, pc, reduction_( op, scp, rhs, x ), maxIterations, verbosity );
 
  192          solver.apply( x, rhs, result );
 
  195        else if( method_ == SolverParameter::superlu )
 
  197          callSuperLU( op, rhs, x, result );
 
  201          DUNE_THROW(NotImplemented,
"ISTLSolverAdapter::operator(): wrong method solver identifier" << method_ );
 
  205      void setMaxLinearIterations( 
unsigned int maxIterations ) { parameter_->setMaxIterations(maxIterations); }
 
  206      void setMaxIterations( 
unsigned int maxIterations ) { parameter_->setMaxIterations(maxIterations); }
 
  208      std::shared_ptr<ISTLSolverParameter> parameter ()
 const { 
return parameter_; }
 
  211      template< 
class ImprovedMatrix >
 
  212      void callSuperLU ( ISTLParallelMatrixAdapterInterface< ImprovedMatrix >& op,
 
  213                         range_type &rhs, domain_type &x,
 
  218        typedef typename ImprovedMatrix :: BaseType Matrix;
 
  219        const ImprovedMatrix& matrix = op.getmat();
 
  220        SuperLU< Matrix > solver( matrix, verbosity );
 
  221        solver.apply( x, rhs, result );
 
  223        DUNE_THROW(NotImplemented,
"ISTLSolverAdapter::callSuperLU: SuperLU solver selected but SuperLU not available!");
 
  228      void callSuperLU ( Op& op, range_type &rhs, domain_type &x,
 
  231        DUNE_THROW(NotImplemented,
"ISTLSolverAdapter::callSuperLU: SuperLU only works for AssembledLinearOperators!");
 
  234      ReductionType reduction_;
 
  237      std::shared_ptr<ISTLSolverParameter> parameter_;
 
  245    template< 
class DiscreteFunction, 
int method = -1,
 
  246              class Preconditioner = Fem::Operator< DiscreteFunction, DiscreteFunction > >
 
  247    class ISTLInverseOperator;
 
  249    template< 
class DiscreteFunction, 
int method, 
class Preconditioner >
 
  250    struct ISTLInverseOperatorTraits
 
  254      typedef Preconditioner PreconditionerType;
 
  256      typedef ISTLBlockVectorDiscreteFunction< typename DiscreteFunction::DiscreteFunctionSpaceType > SolverDiscreteFunctionType ;
 
  257      typedef Dune::Fem::ISTLLinearOperator< DiscreteFunction, DiscreteFunction > AssembledOperatorType;
 
  259      typedef ISTLInverseOperator< DiscreteFunction, method, Preconditioner >  
InverseOperatorType;
 
  260      typedef ISTLSolverParameter SolverParameterType;
 
  263    template< 
class DiscreteFunction, 
int method, 
class Preconditioner >
 
  264    class ISTLInverseOperator : 
public InverseOperatorInterface<
 
  265                                ISTLInverseOperatorTraits< DiscreteFunction,
 
  266                                method, Preconditioner > >
 
  268      typedef ISTLInverseOperatorTraits< DiscreteFunction, method, Preconditioner > Traits;
 
  269      typedef InverseOperatorInterface< Traits > BaseType;
 
  271      friend class InverseOperatorInterface< Traits >;
 
  273      typedef typename BaseType::DomainFunctionType     DomainFunctionType;
 
  274      typedef typename BaseType::RangeFunctionType      RangeFunctionType;
 
  275      typedef typename BaseType::OperatorType           OperatorType;
 
  276      typedef typename BaseType::PreconditionerType     PreconditionerType;
 
  277      typedef typename BaseType::AssembledOperatorType  AssembledOperatorType;
 
  279      using BaseType :: bind;
 
  280      using BaseType :: unbind;
 
  281      using BaseType :: setMaxIterations;
 
  282      using BaseType :: setMaxLinearIterations;
 
  285      typedef typename Traits::SolverDiscreteFunctionType       SolverDiscreteFunctionType;
 
  287      typedef typename DomainFunctionType :: DiscreteFunctionSpaceType
 
  288        DiscreteFunctionSpaceType;
 
  291      typedef typename SolverDiscreteFunctionType::ScalarProductType   ParallelScalarProductType;
 
  292      typedef typename SolverDiscreteFunctionType::DofStorageType      BlockVectorType;
 
  294      typedef ISTLSolverAdapter< method, BlockVectorType > SolverAdapterType;
 
  295      typedef typename SolverAdapterType::ReductionType ReductionType;
 
  299      ISTLInverseOperator ( 
const ISTLSolverParameter & parameter = ISTLSolverParameter() )
 
  300        : BaseType( parameter ), solverAdapter_( ReductionType( parameter_ ), parameter_ )
 
  303      ISTLInverseOperator ( 
const OperatorType &op,
 
  304                            const ISTLSolverParameter & parameter = ISTLSolverParameter() )
 
  305        : ISTLInverseOperator ( parameter )
 
  310      ISTLInverseOperator ( 
const OperatorType &op, PreconditionerType &preconditioner,
 
  311                            const ISTLSolverParameter & parameter = ISTLSolverParameter() )
 
  312        : ISTLInverseOperator( parameter )
 
  314        bind( op, preconditioner );
 
  319      template <
class DomainFunction>
 
  320      int apply( 
const DomainFunction& u, SolverDiscreteFunctionType& w )
 const 
  322        auto& scp = w.scalarProduct();
 
  324        const DiscreteFunctionSpaceType& space = w.space();
 
  327        std::shared_ptr< ISTLPreconditionerType > istlPre;
 
  328        if constexpr (std::is_same< SolverDiscreteFunctionType, RangeFunctionType >::value )
 
  330          typedef ISTLPreconditionAdapter< PreconditionerType > ISTLPreconditionerAdapterType;
 
  331          istlPre.reset( 
new ISTLPreconditionerAdapterType( preconditioner_, space, space ) );
 
  334        if( assembledOperator_ )
 
  336          auto& matrix = assembledOperator_->matrixAdapter( *(solverAdapter_.parameter()) );
 
  338          ISTLPreconditionerType& matrixPre = matrix.preconditionAdapter();
 
  339          ISTLPreconditionerType& precon    = ( preconditioner_ ) ? (*istlPre) : matrixPre;
 
  340          return solve( matrix, scp, precon, u, w );
 
  343        if constexpr (std::is_same< SolverDiscreteFunctionType, RangeFunctionType >::value )
 
  347          typedef ISTLLinearOperatorAdapter< OperatorType >  ISTLOperatorType;
 
  348          ISTLOperatorType istlOperator( *operator_, space, space );
 
  349          return solve( istlOperator, scp, *istlPre, u, w );
 
  352        DUNE_THROW(InvalidStateException,
"ISTLInverseOperator::apply: No valid operator found!");
 
  357      template< 
class OperatorAdapter, 
class ISTLPreconditioner, 
class DomainFunction >
 
  358      int solve ( OperatorAdapter &istlOperator, ParallelScalarProductType &scp,
 
  359                  ISTLPreconditioner &preconditioner,
 
  360                  const DomainFunction& u,
 
  361                  SolverDiscreteFunctionType& w )
 const 
  366          rhs_.reset( 
new SolverDiscreteFunctionType( 
"ISTLInvOp::rhs", w.space() ) );
 
  367          rightHandSideCopied_ = 
false;
 
  370        if( ! rightHandSideCopied_ )
 
  374          rightHandSideCopied_ = 
true;
 
  378        solverAdapter_.setMaxIterations( parameter_->maxIterations() );
 
  379        solverAdapter_( istlOperator, scp, preconditioner, rhs_->blockVector(), w.blockVector(), result );
 
  383      using BaseType :: operator_;
 
  384      using BaseType :: assembledOperator_;
 
  385      using BaseType :: preconditioner_;
 
  387      using BaseType :: rhs_;
 
  388      using BaseType :: x_;
 
  390      using BaseType :: rightHandSideCopied_;
 
  391      using BaseType :: parameter_;
 
  393      mutable SolverAdapterType solverAdapter_;
 
Bi-conjugate Gradient Stabilized (BiCG-STAB)
Definition: solvers.hh:420
 
conjugate gradient method
Definition: solvers.hh:193
 
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
 
gradient method
Definition: solvers.hh:124
 
A linear operator.
Definition: operators.hh:68
 
virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const =0
apply operator to x, scale and add:
 
Preconditioned loop solver.
Definition: solvers.hh:59
 
Minimal Residual Method (MINRES)
Definition: solvers.hh:610
 
Base class for matrix free definition of preconditioners.
Definition: preconditioner.hh:33
 
implements the Generalized Minimal Residual (GMRes) method
Definition: solvers.hh:828
 
Base class for scalar product and norm computation.
Definition: scalarproducts.hh:52
 
virtual real_type norm(const X &x) const
Norm of a right-hand side vector. The vector must be consistent on the interior+border partition.
Definition: scalarproducts.hh:71
 
Various macros to work with Dune module version numbers.
 
Define base class for scalar product and norm.
 
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
 
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485
 
Dune namespace.
Definition: alignedallocator.hh:13
 
Implementations of the inverse operator interface.
 
Statistics about the application of an inverse operator.
Definition: solver.hh:50
 
int iterations
Number of iterations.
Definition: solver.hh:69
 
bool converged
True if convergence criterion has been met.
Definition: solver.hh:75
 
Category
Definition: solvercategory.hh:23
 
@ sequential
Category for sequential solvers.
Definition: solvercategory.hh:25