CPRPreconditioner: extract creation of AMG into a function.

This commit is contained in:
Robert Kloefkorn 2016-02-08 13:19:56 +01:00
parent eb228835c2
commit 37dc877074

View File

@ -52,7 +52,8 @@
#include <opm/autodiff/ParallelOverlappingILU0.hpp> #include <opm/autodiff/ParallelOverlappingILU0.hpp>
namespace Opm namespace Opm
{ {
namespace
namespace ISTLUtility
{ {
/// ///
/// \brief A traits class for selecting the types of the preconditioner. /// \brief A traits class for selecting the types of the preconditioner.
@ -85,6 +86,7 @@ struct CPRSelector
{ {
return new Operator(m); return new Operator(m);
} }
}; };
#if HAVE_MPI #if HAVE_MPI
@ -266,8 +268,49 @@ createEllipticPreconditionerPointer(const M& Ae, double relax,
::EllipticPreconditionerPointer EllipticPreconditionerPointer; ::EllipticPreconditionerPointer EllipticPreconditionerPointer;
return EllipticPreconditionerPointer(new ParallelPreconditioner(Ae, comm, relax)); return EllipticPreconditionerPointer(new ParallelPreconditioner(Ae, comm, relax));
} }
#endif
} // end namespace #endif // #if HAVE_MPI
/// \brief Creates the elliptic preconditioner (ILU0)
/// \param opA The operator representing the matrix of the system.
/// \param relax The relaxation parameter for ILU0.
/// \param comm The object describing the parallelization information and communication.
// \param amgPtr The unique_ptr to be filled (return)
template <class Op, class P, class AMG >
inline void
createAMGPreconditionerPointer( Op& opA, const double relax, const P& comm, std::unique_ptr< AMG >& amgPtr )
{
// type of matrix
typedef typename Op::matrix_type M;
// The coupling metric used in the AMG
typedef Dune::Amg::FirstDiagonal CouplingMetric;
// The coupling criterion used in the AMG
typedef Dune::Amg::SymmetricCriterion<M, CouplingMetric> CritBase;
// The coarsening criterion used in the AMG
typedef Dune::Amg::CoarsenCriterion<CritBase> Criterion;
// TODO: revise choice of parameters
int coarsenTarget=1200;
Criterion criterion(15,coarsenTarget);
criterion.setDebugLevel( 0 ); // no debug information, 1 for printing hierarchy information
criterion.setDefaultValuesIsotropic(2);
criterion.setNoPostSmoothSteps( 1 );
criterion.setNoPreSmoothSteps( 1 );
// for DUNE 2.2 we also need to pass the smoother args
typedef typename AMG::Smoother Smoother;
typedef typename Dune::Amg::SmootherTraits<Smoother>::Arguments SmootherArgs;
SmootherArgs smootherArgs;
smootherArgs.iterations = 1;
smootherArgs.relaxationFactor = relax;
amgPtr.reset( new AMG(opA, criterion, smootherArgs, comm ) );
}
} // end namespace ISTLUtility
struct CPRParameter struct CPRParameter
{ {
@ -348,19 +391,21 @@ createEllipticPreconditionerPointer(const M& Ae, double relax,
Dune::SolverCategory::sequential:Dune::SolverCategory::overlapping Dune::SolverCategory::sequential:Dune::SolverCategory::overlapping
}; };
typedef ISTLUtility::CPRSelector<M,X,X,P> CPRSelectorType ;
//! \brief Elliptic Operator //! \brief Elliptic Operator
typedef typename CPRSelector<M,X,X,P>::Operator Operator; typedef typename CPRSelectorType::Operator Operator;
//! \brief preconditioner for the whole system (here either ILU(0) or ILU(n) //! \brief preconditioner for the whole system (here either ILU(0) or ILU(n)
typedef Dune::Preconditioner<X,X> WholeSystemPreconditioner; typedef Dune::Preconditioner<X,X> WholeSystemPreconditioner;
//! \brief type of the unique pointer to the ilu-0 preconditioner //! \brief type of the unique pointer to the ilu-0 preconditioner
//! used the for the elliptic system //! used the for the elliptic system
typedef typename CPRSelector<M,X,X,P>::EllipticPreconditionerPointer typedef typename CPRSelectorType::EllipticPreconditionerPointer
EllipticPreconditionerPointer; EllipticPreconditionerPointer;
//! \brief amg preconditioner for the elliptic system //! \brief amg preconditioner for the elliptic system
typedef typename CPRSelector<M,X,X,P>::AMG AMG; typedef typename CPRSelectorType::AMG AMG;
/*! \brief Constructor. /*! \brief Constructor.
@ -382,7 +427,7 @@ createEllipticPreconditionerPointer(const M& Ae, double relax,
de_( Ae_.N() ), de_( Ae_.N() ),
ve_( Ae_.M() ), ve_( Ae_.M() ),
dmodified_( A_.N() ), dmodified_( A_.N() ),
opAe_(CPRSelector<M,X,Y,P>::makeOperator(Ae_, commAe)), opAe_(CPRSelectorType::makeOperator(Ae_, commAe)),
precond_(), // ilu0 preconditioner for elliptic system precond_(), // ilu0 preconditioner for elliptic system
amg_(), // amg preconditioner for elliptic system amg_(), // amg preconditioner for elliptic system
pre_(), // copy A will be made be the preconditioner pre_(), // copy A will be made be the preconditioner
@ -395,10 +440,10 @@ createEllipticPreconditionerPointer(const M& Ae, double relax,
// create the preconditioner for the whole system. // create the preconditioner for the whole system.
if( param_.cpr_ilu_n_ == 0 ) { if( param_.cpr_ilu_n_ == 0 ) {
pre_ = createILU0Ptr<M,X>( A_, param_.cpr_relax_, comm_ ); pre_ = ISTLUtility::createILU0Ptr<M,X>( A_, param_.cpr_relax_, comm_ );
} }
else { else {
pre_ = createILUnPtr<M,X>( A_, param_.cpr_ilu_n_, param_.cpr_relax_, comm_ ); pre_ = ISTLUtility::createILUnPtr<M,X>( A_, param_.cpr_ilu_n_, param_.cpr_relax_, comm_ );
} }
} }
@ -552,35 +597,11 @@ createEllipticPreconditionerPointer(const M& Ae, double relax,
{ {
if( amg ) if( amg )
{ {
// The coupling metric used in the AMG ISTLUtility::createAMGPreconditionerPointer( *opAe_ , param_.cpr_relax_, comm, amg_ );
typedef Dune::Amg::FirstDiagonal CouplingMetric;
// The coupling criterion used in the AMG
typedef Dune::Amg::SymmetricCriterion<M, CouplingMetric> CritBase;
// The coarsening criterion used in the AMG
typedef Dune::Amg::CoarsenCriterion<CritBase> Criterion;
// TODO: revise choice of parameters
int coarsenTarget=1200;
Criterion criterion(15,coarsenTarget);
criterion.setDebugLevel( 0 ); // no debug information, 1 for printing hierarchy information
criterion.setDefaultValuesIsotropic(2);
criterion.setNoPostSmoothSteps( 1 );
criterion.setNoPreSmoothSteps( 1 );
// for DUNE 2.2 we also need to pass the smoother args
typedef typename AMG::Smoother Smoother;
typedef typename Dune::Amg::SmootherTraits<Smoother>::Arguments SmootherArgs;
SmootherArgs smootherArgs;
smootherArgs.iterations = 1;
smootherArgs.relaxationFactor = param_.cpr_relax_;
amg_ = std::unique_ptr< AMG > (new AMG(*opAe_, criterion, smootherArgs, comm ));
} }
else else
{ {
precond_ = createEllipticPreconditionerPointer<M,X>( Ae_, param_.cpr_relax_, comm); precond_ = ISTLUtility::createEllipticPreconditionerPointer<M,X>( Ae_, param_.cpr_relax_, comm);
} }
} }
}; };