1#ifndef DUNE_FEM_ISTLPRECONDITIONERWRAPPER_HH
2#define DUNE_FEM_ISTLPRECONDITIONERWRAPPER_HH
35 SolverParameter::ssor,
36 SolverParameter::sor ,
37 SolverParameter::ilu ,
38 SolverParameter::gauss_seidel,
39 SolverParameter::jacobi,
40 SolverParameter::amg_ilu,
41 SolverParameter::amg_jacobi,
48 template <
class MatrixImp>
51 template <
class MatrixImp>
54 template <
class MatrixImp>
96 template<
class MatrixObject,
class X,
class Y,
int method,
int l=1 >
100 typedef typename MatrixObject :: ColumnDiscreteFunctionType DiscreteFunctionType ;
103 typedef typename X::field_type field_type;
104 typedef typename MatrixObject::MatrixType MatrixType;
105 typedef MatrixType
M;
106 typedef typename M::block_type MatrixBlockType;
108 typedef typename DiscreteFunctionType :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType ;
109 typedef typename DiscreteFunctionSpaceType:: DomainFieldType DomainFieldType;
111 static const bool isNumber = (M::block_type::rows == M::block_type::cols) && (M::block_type::rows == 1);
117 typedef FieldMatrixConverter< FlatMatrixBlock, MatrixBlockType > MatrixConverterType;
121 template <
class rowiterator,
bool forward>
122 void iterate (
const M& A, X& xnew,
const X& xold,
const Y& b,
const field_type& w,
123 const DiagonalType& diagInv,
125 const rowiterator endi,
128 typedef typename M::ConstColIterator coliterator;
130 typedef typename Y::block_type bblock;
131 typedef typename X::block_type xblock;
140 const bool hasDiagInv = diagInv.size() > 0 ;
142 const auto nextRow = [&i]()
145 if constexpr ( forward )
151 for (; i!=endi; nextRow() )
153 const coliterator endj=(*i).end();
154 coliterator j=(*i).begin();
155 const auto rowIdx = i.index();
160 xnew[rowIdx] += w*b[rowIdx];
165 if constexpr (isNumber)
168 for (; j.index()<rowIdx; ++j)
169 rhs -= (*j)[0][0] * xold[j.index()];
174 rhs -= (*j)[0][0] * xold[j.index()];
178 v =
rhs * diagInv[ rowIdx ];
180 v =
rhs / (*diag)[0][0];
182 xnew[ rowIdx ] += w*v;
187 for (; j.index()<rowIdx; ++j)
188 (*j).mmv(xold[j.index()],
rhs);
191 (*j).mmv(xold[j.index()],
rhs);
196 MatrixConverterType m( diagInv[ rowIdx ] );
200 (*diag).solve(v,
rhs);
201 xnew[rowIdx].axpy(w,v);
208 void forwardIterate (
const M& A, X& xnew,
const X& xold,
const Y& b,
const field_type& w,
209 const DiagonalType& diagInv )
const
211 bool runParallel = threading_ && (&xnew != &xold);
215 auto doIterate = [
this, &A, &xnew, &xold, &b, &w, &diagInv] ()
217 const auto slice = A.sliceBeginEnd( MPIManager::thread(), MPIManager::numThreads() );
219 iterate( A, xnew, xold, b, w, diagInv,
220 A.slicedBegin( slice.first ), A.slicedEnd( slice.second ),
std::true_type() );
225 MPIManager :: run ( doIterate );
227 catch (
const SingleThreadModeError& e )
236 iterate( A, xnew, xold, b, w, diagInv, A.begin(), A.end(),
std::true_type() );
242 void backwardIterate (
const M& A, X& xnew,
const X& xold,
const Y& b,
const field_type& w,
243 const DiagonalType& diagInv )
const
246 iterate( A, xnew, xold, b, w, diagInv, A.beforeEnd(), A.beforeBegin(),
std::false_type() );
250 const MatrixObject& mObj_;
251 const MatrixType& _A_;
255 DiagonalType diagonalInv_;
257 const bool threading_;
260 ParallelIterative(
const MatrixObject& mObj,
int n=1,
double relax=1.0,
const bool verbose=
false )
262 _A_( mObj.exportMatrix() ),
264 threading_( mObj.threading() )
274 const auto&
space = mObj_.domainSpace();
275 if(
space.continuous() )
278 ISTLBlockVector< FlatMatrixBlock > diagonalInv( &diagonalInv_ );
280 diagonalInv.resize(
space.blockMapper().size());
281 assert(
space.blockMapper().size() == _A_.N() );
286 const auto end = _A_.end();
287 for(
auto row = _A_.begin(); row !=
end; ++row )
290 auto diag = (*row).find( row.index() );
291 if( diag != (*row).end() )
293 MatrixConverterType m( diagonalInv[ row.index() ] );
301 typename DiscreteFunctionSpaceType :: template
302 CommDataHandle< DiscreteFunctionType > :: OperationType operation;
303 space.communicate( diagonalInv, operation );
309 if constexpr( isNumber )
312 for(
auto& diag : diagonalInv )
314 diag = (
std::abs( diag ) < eps ? 1. : 1. / diag );
320 ParallelIterative(
const ParallelIterative& org )
321 : mObj_( org.mObj_ ),
323 _n( org._n ), _w( org._w ),
324 diagonalInv_( org.diagonalInv_ )
329 void pre (X& x, Y& b)
override {}
332 void apply (X& v,
const Y& d)
override
334 const auto&
space = mObj_.domainSpace();
335 const bool continuous =
space.continuous();
338 DiscreteFunctionType tmp(
"ParIt::apply", space, v );
340 static constexpr bool jacobi = (method == SolverParameter::jacobi);
343 if constexpr ( jacobi )
344 xTmp.
reset(
new X(v) );
346 X& x = (jacobi) ? (*xTmp) : v;
348 for (
int i=0; i<_n; ++i)
350 forwardIterate(_A_, v, x, d, _w, diagonalInv_ );
352 if constexpr ( method == SolverParameter::ssor )
359 backwardIterate(_A_, v, x, d, _w, diagonalInv_ );
366 if constexpr ( jacobi )
371 if( continuous && i == _n-1)
378 void post (X& x)
override {}
381 SolverCategory::Category
category ()
const override {
return SolverCategory::sequential; }
384 template<
class MatrixObject,
class X,
class Y >
385 using ParallelSOR = ParallelIterative< MatrixObject, X, Y, SolverParameter::sor>;
387 template<
class MatrixObject,
class X,
class Y >
388 using ParallelSSOR = ParallelIterative< MatrixObject, X, Y, SolverParameter::ssor>;
390 template<
class MatrixObject,
class X,
class Y >
391 using ParallelJacobi = ParallelIterative< MatrixObject, X, Y, SolverParameter::jacobi>;
393 template<
class X,
class Y >
394 class IdentityPreconditionerWrapper :
public Preconditioner<X,Y>
398 typedef X domain_type;
400 typedef Y range_type;
402 typedef typename X::field_type field_type;
405 IdentityPreconditionerWrapper(){}
408 void pre (X& x, Y& b)
override {}
411 void apply (X& v,
const Y& d)
override
420 void post (X& x)
override {}
422 SolverCategory::Category
category ()
const override {
return SolverCategory::sequential; }
429 template<
class MatrixImp>
430 class PreconditionerWrapper
431 :
public Preconditioner<typename MatrixImp :: RowBlockVectorType,
432 typename MatrixImp :: ColBlockVectorType>
434 typedef MatrixImp MatrixType;
435 typedef typename MatrixType :: RowBlockVectorType X;
436 typedef typename MatrixType :: ColBlockVectorType Y;
439 typedef typename MatrixType :: BaseType ISTLMatrixType ;
441 typedef typename MatrixType :: CommunicationType
449 typedef MatrixAdapter< ISTLMatrixType, X, Y > OperatorType;
454 typedef Preconditioner<X,Y> PreconditionerInterfaceType;
461 template <
class XImp,
class YImp>
464 inline static void apply(PreconditionerInterfaceType& preconder,
465 XImp& v,
const YImp& d)
469 inline static void copy(XImp& v,
const YImp& d)
474 template <
class XImp>
475 struct Apply<XImp,XImp>
477 inline static void apply(PreconditionerInterfaceType& preconder,
478 XImp& v,
const XImp& d)
480 preconder.apply( v ,d );
483 inline static void copy(X& v,
const Y& d)
490 typedef X domain_type;
492 typedef Y range_type;
494 typedef typename X::field_type field_type;
497 PreconditionerWrapper (
const PreconditionerWrapper& org,
bool verbose)
499 , preconder_(org.preconder_)
506 PreconditionerWrapper(
bool verbose)
514 template <
class PreconditionerType>
515 PreconditionerWrapper(MatrixType & matrix,
519 const PreconditionerType* p)
521 , preconder_( new PreconditionerType(
matrix, iter, relax ) )
530 template <
class PreconditionerType>
531 PreconditionerWrapper(MatrixType & matrix,
bool verbose,
532 PreconditionerType* p)
541 template <
class PreconditionerType>
542 PreconditionerWrapper(MatrixType & matrix,
546 const PreconditionerType* p ,
547 const CommunicationType& comm)
551 : op_( new OperatorType(
matrix ) )
553 , preconder_( createAMGPreconditioner(
comm, iter, relax, p) )
560 void pre (X& x, Y& b)
override
567 preconder_->pre(x,b);
573 void apply (X& v,
const Y& d)
override
578 Apply<X,Y>::apply( *preconder_ , v, d );
582 Apply<X,Y>::copy( v, d );
587 void post (X& x)
override
598 SolverCategory::Category
category ()
const override
600 return (preconder_ ? preconder_->category() : SolverCategory::sequential);
604 template <
class Smoother>
605 PreconditionerInterfaceType*
606 createAMGPreconditioner(
const CommunicationType& comm,
607 int iter, field_type relax,
const Smoother* )
617 SmootherArgs smootherArgs;
620 smootherArgs.relaxationFactor = relax ;
624 criterion.setDefaultValuesIsotropic(2);
625 criterion.setAlpha(.67);
626 criterion.setBeta(1.0e-8);
627 criterion.setMaxLevel(10);
628 if( verbose_ && Parameter :: verbose() )
629 criterion.setDebugLevel( 1 );
631 criterion.setDebugLevel( 0 );
646 return new AMG(*op_, criterion, smootherArgs);
656 template <
class MatrixObject >
657 class ISTLMatrixAdapterFactory ;
659 template <
class DomainSpace,
class RangeSpace,
class DomainBlock,
class RangeBlock,
660 template <
class,
class,
class,
class>
class MatrixObject >
661 class ISTLMatrixAdapterFactory< MatrixObject< DomainSpace, RangeSpace, DomainBlock, RangeBlock > >
663 typedef DomainSpace DomainSpaceType ;
664 typedef RangeSpace RangeSpaceType;
667 typedef MatrixObject< DomainSpaceType, RangeSpaceType, DomainBlock, RangeBlock > MatrixObjectType;
668 typedef typename MatrixObjectType :: MatrixType MatrixType;
669 typedef ISTLParallelMatrixAdapterInterface< MatrixType > MatrixAdapterInterfaceType;
673 matrixAdapter(
const MatrixObjectType& matrixObj,
674 const ISTLSolverParameter& param)
677 if( matrixObj.domainSpace().continuous() )
679 typedef LagrangeParallelMatrixAdapter< MatrixType > MatrixAdapterImplementation;
680 ptr.
reset( matrixAdapterObject( matrixObj, (MatrixAdapterImplementation *)
nullptr, param ) );
684 typedef DGParallelMatrixAdapter< MatrixType > MatrixAdapterImplementation;
685 ptr.
reset( matrixAdapterObject( matrixObj, (MatrixAdapterImplementation *)
nullptr, param ) );
691 template <
class MatrixAdapterType>
692 static MatrixAdapterType*
693 matrixAdapterObject(
const MatrixObjectType& matrixObj,
694 const MatrixAdapterType*,
695 const ISTLSolverParameter& param )
697 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
698 return new MatrixAdapterType( matrixObj.exportMatrix(),
699 matrixObj.domainSpace(), matrixObj.rangeSpace(), PreConType(param.verbose()),
700 matrixObj.threading() );
705#ifndef DISABLE_ISTL_PRECONDITIONING
707 template <
class Space,
class DomainBlock,
class RangeBlock,
708 template <
class,
class,
class,
class>
class MatrixObject >
709 class ISTLMatrixAdapterFactory< MatrixObject< Space, Space, DomainBlock, RangeBlock > >
712 typedef Space DomainSpaceType ;
713 typedef Space RangeSpaceType;
715 typedef MatrixObject< DomainSpaceType, RangeSpaceType, DomainBlock, RangeBlock > MatrixObjectType;
716 typedef typename MatrixObjectType :: MatrixType MatrixType;
717 typedef typename MatrixType :: BaseType ISTLMatrixType ;
718 typedef Fem::PreconditionerWrapper< MatrixType > PreconditionAdapterType;
721 template <
class MatrixAdapterType,
class PreconditionerType>
722 static MatrixAdapterType*
723 createMatrixAdapter(
const MatrixAdapterType*,
724 const PreconditionerType* preconditioning,
726 const DomainSpaceType& domainSpace,
727 const RangeSpaceType& rangeSpace,
728 const double relaxFactor,
732 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
733 PreConType preconAdapter(matrix, numIterations, relaxFactor, verbose, preconditioning );
734 return new MatrixAdapterType(matrix, domainSpace, rangeSpace, preconAdapter );
737 template <
class MatrixAdapterType,
class PreconditionerType>
738 static MatrixAdapterType*
739 createAMGMatrixAdapter(
const MatrixAdapterType*,
740 const PreconditionerType* preconditioning,
742 const DomainSpaceType& domainSpace,
743 const RangeSpaceType& rangeSpace,
744 const double relaxFactor,
748 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
749 PreConType preconAdapter(matrix, numIterations, relaxFactor, solverVerbose,
750 preconditioning, domainSpace.gridPart().comm() );
751 return new MatrixAdapterType(matrix, domainSpace, rangeSpace, preconAdapter );
754 template <
class MatrixAdapterType>
755 static MatrixAdapterType*
756 matrixAdapterObject(
const MatrixObjectType& matrixObj,
757 const MatrixAdapterType*,
758 const ISTLSolverParameter& param )
760 int preconditioning = param.preconditionMethod(
761 ISTLPreconditionMethods::supportedPreconditionMethods() );
762 const double relaxFactor = param.relaxation();
763 const size_t numIterations = param.preconditionerIteration();
765 const DomainSpaceType& domainSpace = matrixObj.domainSpace();
766 const RangeSpaceType& rangeSpace = matrixObj.rangeSpace();
768 MatrixType&
matrix = matrixObj.exportMatrix();
769 const auto procs = domainSpace.gridPart().comm().size();
771 const bool verbose = param.verbose();
773 typedef typename MatrixType :: BaseType ISTLMatrixType;
774 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
776 typedef typename MatrixObjectType :: RowBlockVectorType RowBlockVectorType;
777 typedef typename MatrixObjectType :: ColumnBlockVectorType ColumnBlockVectorType;
780 if( preconditioning == SolverParameter::none )
782 return new MatrixAdapterType( matrix, domainSpace, rangeSpace, PreConType(param.verbose()) );
785 else if( preconditioning == SolverParameter::ssor )
787 typedef ParallelSSOR<MatrixObjectType, RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
788 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
789 PreConType preconAdapter( matrix, verbose,
new PreconditionerType( matrixObj, numIterations, relaxFactor, verbose ) );
790 return new MatrixAdapterType( matrix, domainSpace, rangeSpace, preconAdapter );
793 else if(preconditioning == SolverParameter::sor || preconditioning == SolverParameter::gauss_seidel)
795 typedef ParallelSOR<MatrixObjectType, RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
796 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
797 PreConType preconAdapter( matrix, verbose,
new PreconditionerType( matrixObj, numIterations,
798 (preconditioning == SolverParameter::gauss_seidel) ? 1.0 : relaxFactor,
verbose ) );
799 return new MatrixAdapterType( matrix, domainSpace, rangeSpace, preconAdapter );
802 else if(preconditioning == SolverParameter::ilu)
805 DUNE_THROW(InvalidStateException,
"ISTL::SeqILU not working in parallel computations");
807 typedef SeqILU<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
808 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
810 PreConType preconAdapter( matrix, verbose,
new PreconditionerType( matrix, numIterations, relaxFactor, param.fastILUStorage()) );
811 return new MatrixAdapterType( matrix, domainSpace, rangeSpace, preconAdapter );
814 else if(preconditioning == SolverParameter::jacobi)
816 typedef ParallelJacobi<MatrixObjectType, RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
817 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
818 PreConType preconAdapter( matrix, verbose,
new PreconditionerType( matrixObj, numIterations, relaxFactor, verbose ) );
819 return new MatrixAdapterType( matrix, domainSpace, rangeSpace, preconAdapter );
822 else if(preconditioning == SolverParameter::amg_ilu)
825 typedef SeqILU<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
826 return createAMGMatrixAdapter( (MatrixAdapterType *)
nullptr,
827 (PreconditionerType*)
nullptr,
828 matrix, domainSpace, rangeSpace, relaxFactor, numIterations,
832 else if(preconditioning == SolverParameter::amg_jacobi)
834 typedef SeqJac<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType,1> PreconditionerType;
835 return createAMGMatrixAdapter( (MatrixAdapterType *)
nullptr,
836 (PreconditionerType*)
nullptr,
837 matrix, domainSpace, rangeSpace, relaxFactor, numIterations,
841 else if(preconditioning == SolverParameter::ildl)
844 DUNE_THROW(InvalidStateException,
"ISTL::SeqILDL not working in parallel computations");
846 PreConType preconAdapter( matrix, verbose,
new SeqILDL<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType>( matrix , relaxFactor ) );
847 return new MatrixAdapterType( matrix, domainSpace, rangeSpace, preconAdapter );
851 preConErrorMsg(preconditioning);
853 return new MatrixAdapterType(matrix, domainSpace, rangeSpace, PreConType(verbose) );
856 typedef ISTLParallelMatrixAdapterInterface< MatrixType > MatrixAdapterInterfaceType;
858 static void preConErrorMsg(
int preCon)
861 std::cerr <<
"ERROR: Wrong precoditioning number (p = " << preCon;
873 DUNE_THROW(NotImplemented,
"Wrong precoditioning selected");
879 matrixAdapter(
const MatrixObjectType& matrixObj,
880 const ISTLSolverParameter& param)
882 const ISTLSolverParameter* parameter =
dynamic_cast< const ISTLSolverParameter*
> (¶m);
886 paramPtr.
reset(
new ISTLSolverParameter( param ) );
887 parameter = paramPtr.operator->();
891 if( matrixObj.domainSpace().continuous() )
893 typedef LagrangeParallelMatrixAdapter< MatrixType > MatrixAdapterImplementation;
894 ptr.
reset( matrixAdapterObject( matrixObj, (MatrixAdapterImplementation *)
nullptr, *parameter ) );
898 typedef DGParallelMatrixAdapter< MatrixType > MatrixAdapterImplementation;
899 ptr.
reset( matrixAdapterObject( matrixObj, (MatrixAdapterImplementation *)
nullptr, *parameter ) );
SolverCategory::Category category() const override
void pre(Domain &x, Range &b)
AMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs &smootherArgs, const Parameters &parms)
int coarsenTarget() const
OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
static constexpr size_type M()
#define DUNE_THROW(E,...)
const Communication & comm() const
Dune::Fem::Double abs(const Dune::Fem::Double &a)
Definition double.hh:942
static void check(const Matrix &mat)
static ParameterContainer & container()
Definition io/parameter.hh:199
Definition io/parameter.hh:576
T getValue(const std::string &key) const
get mandatory parameter
Definition reader.hh:161
Definition istlpreconditioner.hh:32
static std::vector< int > supportedPreconditionMethods()
Definition istlpreconditioner.hh:33
Definition istlpreconditioner.hh:49
Definition istlpreconditioner.hh:55
Definition istlpreconditioner.hh:58
virtual bool fastILUStorage() const
Definition istlpreconditioner.hh:81
LocalParameter< SolverParameter, ISTLSolverParameter > BaseType
Definition istlpreconditioner.hh:59
ISTLSolverParameter(const std::string &keyPrefix, const ParameterReader ¶meter=Parameter::container())
Definition istlpreconditioner.hh:68
virtual double overflowFraction() const
Definition istlpreconditioner.hh:76
ISTLSolverParameter(const ParameterReader ¶meter=Parameter::container())
Definition istlpreconditioner.hh:64
ISTLSolverParameter(const SolverParameter &sp)
Definition istlpreconditioner.hh:72
Definition solver/parameter.hh:25
const ParameterReader & parameter() const
Definition solver/parameter.hh:81
const std::string & keyPrefix() const
Definition solver/parameter.hh:79