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:419
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:609
Base class for matrix free definition of preconditioners.
Definition: preconditioner.hh:33
implements the Generalized Minimal Residual (GMRes) method
Definition: solvers.hh:827
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, m)
Definition: exceptions.hh:218
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
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