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, m)
Definition: exceptions.hh:218
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