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=";
135 std::cout <<
"custom" << std::endl;
137 std::cout << SolverParameter::preconditionMethodTable( precondMethod_ ) << std::endl;
142 if( method_ == SolverParameter::gmres )
146 const int extra = ( preconditioner_ ) ? 2 : 1 ;
147 v_.reserve( parameter_->gmresRestart()+extra );
148 for(
int i=0; i<=parameter_->gmresRestart(); ++i )
150 v_.emplace_back( DiscreteFunction(
"GMRes::v", u.space() ) );
152 if( preconditioner_ )
153 v_.emplace_back( DiscreteFunction(
"GMRes::z", u.space() ) );
157 numIter = LinearSolver::gmres( *operator_, preconditioner_,
158 v_, w, u, parameter_->gmresRestart(),
159 parameter_->tolerance(), parameter_->maxIterations(),
160 parameter_->errorMeasure(), os );
162 else if( method_ == SolverParameter::bicgstab )
166 v_.emplace_back( DomainFunctionType(
"BiCGStab::r", u.space() ) );
167 v_.emplace_back( DomainFunctionType(
"BiCGStab::r*", u.space() ) );
168 v_.emplace_back( DomainFunctionType(
"BiCGStab::p", u.space() ) );
169 v_.emplace_back( DomainFunctionType(
"BiCGStab::s", u.space() ) );
170 v_.emplace_back( DomainFunctionType(
"BiCGStab::tmp", u.space() ) );
171 if( preconditioner_ )
172 v_.emplace_back( DomainFunctionType(
"BiCGStab::z", u.space() ) );
176 numIter = LinearSolver::bicgstab( *operator_, preconditioner_,
178 parameter_->tolerance(), parameter_->maxIterations(),
179 parameter_->errorMeasure(), os );
181 else if( method_ == SolverParameter::cg )
185 v_.emplace_back( DomainFunctionType(
"CG::h", u.space() ) );
186 v_.emplace_back( DomainFunctionType(
"CG::r", u.space() ) );
187 v_.emplace_back( DomainFunctionType(
"CG::p", u.space() ) );
189 if( preconditioner_ )
191 v_.emplace_back( DomainFunctionType(
"CG::s", u.space() ) );
192 v_.emplace_back( DomainFunctionType(
"CG::q", u.space() ) );
197 numIter = LinearSolver::cg( *operator_, preconditioner_,
199 parameter_->tolerance(), parameter_->maxIterations(),
200 parameter_->errorMeasure(), os );
204 DUNE_THROW(InvalidStateException,
"KrylovInverseOperator: invalid method " << method_ );
210 template <
class LinearOperator>
211 KrylovInverseOperator (
const LinearOperator &op,
212 const PreconditionerType *preconditioner,
213 const SolverParameter ¶meter = SolverParameter(Parameter::container()) )
214 : KrylovInverseOperator( parameter )
217 BaseType::bind( op, *preconditioner );
219 BaseType::bind( op );
223 template <
class LinearOperator>
224 void createPreconditioner(
const LinearOperator &op )
226 if( precondMethod_ > 0 && std::is_base_of< AssembledOperator< DomainFunctionType, DomainFunctionType >, LinearOperator > :: value )
228 const int n = parameter_->preconditionerIteration();
229 const double w = parameter_->relaxation();
231 if( precondMethod_ == SolverParameter::jacobi )
234 precondObj_.reset(
new FemJacobiPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
236 else if( precondMethod_ == SolverParameter::gauss_seidel )
239 precondObj_.reset(
new FemGaussSeidelPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
241 else if( precondMethod_ == SolverParameter::sor )
244 precondObj_.reset(
new FemSORPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
246 else if( precondMethod_ == SolverParameter::ssor )
249 precondObj_.reset(
new FemSSORPreconditioning< DomainFunctionType, LinearOperator >( op, n, w ) );
255 preconditioner_ = precondObj_.operator->();
260 using BaseType :: operator_;
261 using BaseType :: preconditioner_;
263 using BaseType :: parameter_;
264 using BaseType :: iterations_;
266 std::unique_ptr< PreconditionerType > precondObj_;
268 mutable std::vector< DomainFunctionType > v_;
273 const int precondMethod_;
280 template<
class DiscreteFunction >
281 using CgInverseOperator = KrylovInverseOperator< DiscreteFunction, SolverParameter :: cg >;
287 template<
class DiscreteFunction >
288 using BicgstabInverseOperator = KrylovInverseOperator< DiscreteFunction, SolverParameter :: bicgstab >;
294 template<
class DiscreteFunction >
295 using GmresInverseOperator = KrylovInverseOperator< DiscreteFunction, SolverParameter :: gmres >;
301 template<
class DiscreteFunction >
302 using ParDGGeneralizedMinResInverseOperator = GmresInverseOperator< DiscreteFunction >;
307 template<
class DiscreteFunction >
308 using ParDGBiCGStabInverseOperator = BicgstabInverseOperator< DiscreteFunction >;
310 template <
class DiscreteFunctionType,
class OpType >
311 using OEMCGOp = CgInverseOperator< DiscreteFunctionType >;
313 template <
class DiscreteFunctionType,
class OpType >
314 using OEMBICGSTABOp = BicgstabInverseOperator< DiscreteFunctionType >;
316 template <
class DiscreteFunctionType,
class OpType >
317 using OEMBICGSQOp = BicgstabInverseOperator< DiscreteFunctionType >;
319 template <
class DiscreteFunctionType,
class OpType >
320 using OEMGMRESOp = GmresInverseOperator< DiscreteFunctionType >;
322 template <
class DiscreteFunctionType,
class OpType >
323 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