Commit edf89920 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Add check whether preconditioners and solvers can be used with the given matrix/vector type

parent 832af288
Pipeline #5678 passed with stage
in 88 minutes and 8 seconds
......@@ -2,6 +2,7 @@
#include <memory>
#include <type_traits>
#include <dune/common/std/type_traits.hh>
namespace AMDiS
{
......@@ -83,6 +84,20 @@ namespace AMDiS
// ---------------------------------------------------------------------------
template <template <class...> class Op, typename... Args>
struct DetectedType
{
using base = Dune::Std::detected_or<Dune::Std::nonesuch, Op, Args...>;
using type = typename base::type;
static constexpr bool value = base::value_t::value;
};
/// Shortcut for the detected type-traits
#define DETECTED(...) DetectedType<__VA_ARGS__>
// ---------------------------------------------------------------------------
/// A variadic type list
template <class... Ts>
struct Types {};
......
......@@ -38,10 +38,16 @@ namespace AMDiS
template <class Smoother, class LinOp, class Criterion, class Comm>
static std::unique_ptr<PrecBase>
create([[maybe_unused]] std::string prefix, LinOp const& linOp, Criterion const& criterion, SmootherArgs<Smoother> const& smootherArgs, Comm const& comm)
create(std::string, LinOp const& linOp, Criterion const& criterion,
SmootherArgs<Smoother> const& smootherArgs, Comm const& comm)
{
using Solver = Dune::Amg::AMG<LinOp, typename Traits::X, Smoother, Comm>;
return std::make_unique<Solver>(linOp, criterion, smootherArgs, comm);
using Amg = DETECTED(Dune::Amg::AMG, LinOp, typename Traits::X, Smoother, Comm);
if constexpr (Amg::value) {
return std::make_unique<typename Amg::type>(linOp, criterion, smootherArgs, comm);
} else {
error_exit("Dune::Amg::AMG not supported.");
return nullptr;
}
}
};
......@@ -58,13 +64,18 @@ namespace AMDiS
template <class Smoother, class LinOp, class Criterion>
static std::unique_ptr<PrecBase>
create(std::string prefix, LinOp const& linOp, Criterion const& criterion, [[maybe_unused]] SmootherArgs<Smoother> const& smootherArgs,
Dune::Amg::SequentialInformation const& comm)
create(std::string prefix, LinOp const& linOp, Criterion const& criterion,
SmootherArgs<Smoother> const&, Dune::Amg::SequentialInformation const& comm)
{
bool symmetric = Parameters::get<bool>(prefix + "->symmetric").value_or(true);
using Solver = Dune::Amg::FastAMG<LinOp, typename Traits::X, Dune::Amg::SequentialInformation>;
return std::make_unique<Solver>(linOp, criterion, criterion, symmetric, comm);
using FastAmg = DETECTED(Dune::Amg::FastAMG, LinOp, typename Traits::X, Dune::Amg::SequentialInformation);
if constexpr (FastAmg::value) {
return std::make_unique<typename FastAmg::type>(linOp, criterion, criterion, symmetric, comm);
} else {
error_exit("Dune::Amg::FastAMG not supported.");
return nullptr;
}
}
template <class Smoother, class LinOp, class Criterion, class SmootherArgs, class Comm,
......@@ -96,7 +107,8 @@ namespace AMDiS
template <class Smoother, class LinOp, class Criterion, class Comm>
static std::unique_ptr<PrecBase>
create(std::string prefix, LinOp const& linOp, Criterion const& criterion, [[maybe_unused]] SmootherArgs<Smoother> const& smootherArgs, Comm const& comm)
create(std::string prefix, LinOp const& linOp, Criterion const& criterion,
[[maybe_unused]] SmootherArgs<Smoother> const& smootherArgs, Comm const& comm)
{
std::string solver = Parameters::get<std::string>(prefix + "->krylov solver").value_or("default");
......@@ -108,39 +120,51 @@ namespace AMDiS
if (solver == "pcg" ||
solver == "default")
{
using Solver = Dune::Amg::KAMG<LinOp, X, Smoother, Comm, Dune::GeneralizedPCGSolver<X>>;
return std::make_unique<Solver>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
using KAmgPCG = DETECTED(Dune::Amg::KAMG, LinOp, X, Smoother, Comm, Dune::GeneralizedPCGSolver<X>);
if constexpr (KAmgPCG::value) {
return std::make_unique<typename KAmgPCG::type>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
}
}
#if DUNE_VERSION_GTE(DUNE_ISTL,2,7)
else if (solver == "fcg")
{
using Solver = Dune::Amg::KAMG<LinOp, X, Smoother, Comm, Dune::RestartedFCGSolver<X>>;
return std::make_unique<Solver>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
using KAmgFCG = DETECTED(Dune::Amg::KAMG, LinOp, X, Smoother, Comm, Dune::RestartedFCGSolver<X>);
if constexpr (KAmgFCG::value) {
return std::make_unique<typename KAmgFCG::type>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
}
}
else if (solver == "cfcg")
{
using Solver = Dune::Amg::KAMG<LinOp, X, Smoother, Comm, Dune::CompleteFCGSolver<X>>;
return std::make_unique<Solver>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
using KAmgCFCG = DETECTED(Dune::Amg::KAMG, LinOp, X, Smoother, Comm, Dune::CompleteFCGSolver<X>);
if constexpr (KAmgCFCG::value) {
return std::make_unique<typename KAmgCFCG::type>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
}
}
#endif
else if (solver == "bicgstab" ||
solver == "bcgs")
{
using Solver = Dune::Amg::KAMG<LinOp, X, Smoother, Comm, Dune::BiCGSTABSolver<X>>;
return std::make_unique<Solver>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
using KAmgBCGS = DETECTED(Dune::Amg::KAMG, LinOp, X, Smoother, Comm, Dune::BiCGSTABSolver<X>);
if constexpr (KAmgBCGS::value) {
return std::make_unique<typename KAmgBCGS::type>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
}
}
else if (solver == "minres")
{
using Solver = Dune::Amg::KAMG<LinOp, X, Smoother, Comm, Dune::MINRESSolver<X>>;
return std::make_unique<Solver>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
using KAmgMinRes = DETECTED(Dune::Amg::KAMG, LinOp, X, Smoother, Comm, Dune::MINRESSolver<X>);
if constexpr (KAmgMinRes::value) {
return std::make_unique<typename KAmgMinRes::type>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
}
}
#if 0
// NOTE: can not be constructed inside the KAMG precon, since additional constructor argument.
// Needs something like ConstructionTraits for solvers.
else if (solver == "gmres")
{
using Solver = Dune::Amg::KAMG<LinOp, X, Smoother, Comm, Dune::RestartedGMResSolver<X>>;
return std::make_unique<Solver>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
using KAmgGMRes = DETECTED(Dune::Amg::KAMG, LinOp, X, Smoother, Comm, Dune::RestartedGMResSolver<X>);
if constexpr (KAmgGMRes::value) {
return std::make_unique<typename KAmgGMRes::type>(linOp, criterion, smootherArgs, maxLevelKrylovSteps, minDefectReduction, comm);
}
}
#endif
else
......@@ -148,6 +172,9 @@ namespace AMDiS
error_exit("Unknown coarse space solver {} given for parameter `{}`.", solver, prefix + "->coarse space solver");
return nullptr;
}
error_exit("Dune::Amg::KAMG not supported.");
return nullptr;
}
};
......
......@@ -2,9 +2,13 @@
#include <amdis/CreatorInterface.hpp>
#include <amdis/CreatorMap.hpp>
#include <amdis/ProblemStatTraits.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/linearalgebra/istl/AMGPrecon.hpp>
#include <amdis/linearalgebra/istl/CreatorInterfaces.hpp>
#include <amdis/linearalgebra/istl/Preconditioners.hpp>
#include <amdis/linearalgebra/istl/PreconWrapper.hpp>
#include <amdis/linearalgebra/istl/Traits.hpp>
#include <amdis/linearalgebra/istl/precompiled/Preconditioners.hpp>
namespace AMDiS
......@@ -61,9 +65,15 @@ namespace AMDiS
using Super::Super; // inheriting constructor
std::unique_ptr<typename Traits::Prec>
create(typename Traits::M const& mat, [[maybe_unused]] typename Traits::Comm const& comm) const override
create(typename Traits::M const& mat, typename Traits::Comm const&) const override
{
return std::make_unique<Precon>(mat, this->iter_, this->w_);
using field_type = typename Precon::scalar_field_type;
if (std::is_constructible_v<Precon, TYPEOF(mat), int, field_type>)
return std::make_unique<Precon>(mat, this->iter_, field_type(this->w_));
else {
error_exit("Cannot use the preconditioner {} for this matrix type",Dune::className<Precon>());
return nullptr;
}
}
};
......@@ -77,10 +87,16 @@ namespace AMDiS
using Super::Super; // inheriting constructor
std::unique_ptr<typename Traits::Prec>
create([[maybe_unused]] typename Traits::M const& mat, [[maybe_unused]] typename Traits::Comm const& comm) const override
create(typename Traits::M const&, typename Traits::Comm const&) const override
{
using Precon = Dune::Richardson<X, Y>;
return std::make_unique<Precon>(this->w_);
using field_type = typename Precon::scalar_field_type;
if (std::is_constructible_v<Precon, field_type>)
return std::make_unique<Precon>(field_type(this->w_));
else {
error_exit("Cannot use the preconditioner {} for this matrix type",Dune::className<Precon>());
return nullptr;
}
}
};
......@@ -94,10 +110,16 @@ namespace AMDiS
using Super::Super; // inheriting constructor
std::unique_ptr<typename Traits::Prec>
create(typename Traits::M const& mat, [[maybe_unused]] typename Traits::Comm const& comm) const override
create(typename Traits::M const& mat, typename Traits::Comm const&) const override
{
using Precon = Dune::SeqILDL<M, X, Y>;
return std::make_unique<Precon>(mat, this->w_);
using field_type = typename Precon::scalar_field_type;
if (std::is_constructible_v<Precon, TYPEOF(mat), field_type>)
return std::make_unique<Precon>(mat, field_type(this->w_));
else {
error_exit("Cannot use the preconditioner {} for this matrix type",Dune::className<Precon>());
return nullptr;
}
}
};
......@@ -121,7 +143,13 @@ namespace AMDiS
"Dune::ParSSOR preconditioner can be used with overlapping domain decomposition.");
using Precon = Dune::ParSSOR<M,X,Y,Comm>;
return std::make_unique<Precon>(mat, this->iter_, this->w_, comm.get());
using field_type = typename Precon::field_type;
if (std::is_constructible_v<Precon, TYPEOF(mat), int, field_type, TYPEOF(comm.get())>)
return std::make_unique<Precon>(mat, this->iter_, field_type(this->w_), comm.get());
else {
error_exit("Cannot use the preconditioner {} for this matrix type",Dune::className<Precon>());
return nullptr;
}
}
};
......@@ -212,20 +240,6 @@ namespace AMDiS
/// Adds default creators for preconditioners for ISTL.
/**
* Adds creators for istl preconditioners.
* - *diag*, *jacobi*: Diagonal preconditioner (Default), \see Dune::SeqJac
* - *gs*, *gauss_seidel**: Gauss-Seidel preconditioner, \see Dune::SeqGS
* - *sor*: Successive Overrelaxation methods, \see Dune::SeqSOR
* - *ssor*: Symmetric Successive Overrelaxation methods, \see Dune::SeqSSOR
* - *pssor*: A parallel SSOR preconditioner (requires overlap), \see Dune::ParSSOR
* - *richardson*: Richardson methods, \see Dune::Richardson
* - *solver*: Turns an InverseOperator into a Preconditioner, \see Dune::InverseOperator2Preconditioner
* - *bjacobi*: Block-Jacobi methods, \see Dune::BlockPreconditioner, \see Dune::NoverlappingBlockPreconditioner
* - *ilu,ilu0*: Incomplete LU factorization, \see Dune::SeqILU
* - *ildl*: Incomplete LDL factorization, \see Dune::SeqILDL
* - *amg*,*fastamg*,*kamg*: Algebraic multigrid methods, \see Dune::Amg::AMG, \see Dune::Amg::FastAMG, \see Dune::Amg::KAMG
**/
template <class Traits>
class DefaultCreators<ISTLPreconCreatorInterface<Traits>>
{
......@@ -242,48 +256,53 @@ namespace AMDiS
public:
static void init()
{
auto jacobi = new PreconCreator<Dune::SeqJac<M,X,Y>>;
Map::addCreator("diag", jacobi);
Map::addCreator("jacobi", jacobi);
using SeqJac = DETECTED(Preconditioners::SeqJac,M,X,Y);
if constexpr (SeqJac::value) {
auto jacobi = new PreconCreator<typename SeqJac::type>;
Map::addCreator("diag", jacobi);
Map::addCreator("jacobi", jacobi);
}
auto gs = new PreconCreator<Dune::SeqGS<M,X,Y>>;
Map::addCreator("gs", gs);
Map::addCreator("gauss_seidel", gs);
using SeqGS = DETECTED(Preconditioners::SeqGS,M,X,Y);
if constexpr (SeqGS::value) {
auto gs = new PreconCreator<typename SeqGS::type>;
Map::addCreator("gs", gs);
Map::addCreator("gauss_seidel", gs);
}
auto sor = new PreconCreator<Dune::SeqSOR<M,X,Y>>;
Map::addCreator("sor", sor);
using SeqSOR = DETECTED(Preconditioners::SeqSOR,M,X,Y);
if constexpr (SeqSOR::value)
Map::addCreator("sor", new PreconCreator<typename SeqSOR::type>);
auto ssor = new PreconCreator<Dune::SeqSSOR<M,X,Y>>;
Map::addCreator("ssor", ssor);
using SeqSSOR = DETECTED(Preconditioners::SeqSSOR,M,X,Y);
if constexpr (SeqSSOR::value)
Map::addCreator("ssor", new PreconCreator<typename SeqSSOR::type>);
using SeqILU = DETECTED(Preconditioners::SeqILU,M,X,Y);
if constexpr (SeqILU::value) {
auto ilu = new PreconCreator<typename SeqILU::type>;
Map::addCreator("ilu", ilu);
Map::addCreator("ilu0", ilu);
}
using SeqILDL = DETECTED(Preconditioners::SeqILDL,M,X,Y);
if constexpr (SeqILDL::value)
Map::addCreator("ildl", new PreconCreator<typename SeqILDL::type>);
init_ilu(std::is_arithmetic<typename FTraits::field_type>{});
init_amg(std::is_same<typename FTraits::real_type, double>{});
auto richardson = new PreconCreator<Dune::Richardson<X,Y>>;
Map::addCreator("richardson", richardson);
Map::addCreator("default", richardson);
using Richardson = DETECTED(Dune::Richardson,X,Y);
if constexpr (Richardson::value) {
auto richardson = new PreconCreator<typename Richardson::type>;
Map::addCreator("richardson", richardson);
Map::addCreator("default", richardson);
}
auto solver = new PreconCreator<tag::solver>;
Map::addCreator("solver", solver);
Map::addCreator("solver", new PreconCreator<tag::solver>);
init_bjacobi(Types<TYPEOF(std::declval<typename Traits::Comm>().get())>{}, Dune::PriorityTag<10>{});
}
static void init_ilu(std::false_type)
{
warning("ILU preconditioners not created for the matrix with field_type = {}.",
Dune::className<typename FTraits::field_type>());
}
static void init_ilu(std::true_type)
{
auto ilu = new PreconCreator<Dune::SeqILU<M,X,Y>>;
Map::addCreator("ilu", ilu);
Map::addCreator("ilu0", ilu);
auto ildl = new PreconCreator<Dune::SeqILDL<M,X,Y>>;
Map::addCreator("ildl", ildl);
}
static void init_amg(std::false_type)
{
......@@ -306,11 +325,13 @@ namespace AMDiS
template <class Comm>
static void init_bjacobi(Types<Comm>, Dune::PriorityTag<1>)
{
auto pssor = new PreconCreator<Dune::ParSSOR<M,X,Y,Comm>>;
Map::addCreator("pssor", pssor);
using ParSSOR = DETECTED(Dune::ParSSOR,M,X,Y,Comm);
if constexpr (ParSSOR::value) {
auto pssor = new PreconCreator<typename ParSSOR::type>;
Map::addCreator("pssor", pssor);
}
auto bjacobi = new PreconCreator<tag::bjacobi>;
Map::addCreator("bjacobi", bjacobi);
Map::addCreator("bjacobi", new PreconCreator<tag::bjacobi>);
}
};
......
#pragma once
#include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/preconditioners.hh>
namespace AMDiS
{
/// List of preconditioners for ISTL.
/**
* Adds creators for istl preconditioners.
* - *diag*, *jacobi*: Diagonal preconditioner (Default), \see Dune::SeqJac
* - *gs*, *gauss_seidel**: Gauss-Seidel preconditioner, \see Dune::SeqGS
* - *sor*: Successive Overrelaxation methods, \see Dune::SeqSOR
* - *ssor*: Symmetric Successive Overrelaxation methods, \see Dune::SeqSSOR
* - *pssor*: A parallel SSOR preconditioner (requires overlap), \see Dune::ParSSOR
* - *richardson*: Richardson methods, \see Dune::Richardson
* - *solver*: Turns an InverseOperator into a Preconditioner, \see Dune::InverseOperator2Preconditioner
* - *bjacobi*: Block-Jacobi methods, \see Dune::BlockPreconditioner, \see Dune::NoverlappingBlockPreconditioner
* - *ilu,ilu0*: Incomplete LU factorization, \see Dune::SeqILU
* - *ildl*: Incomplete LDL factorization, \see Dune::SeqILDL
* - *amg*,*fastamg*,*kamg*: Algebraic multigrid methods, \see Dune::Amg::AMG, \see Dune::Amg::FastAMG, \see Dune::Amg::KAMG
**/
namespace Preconditioners
{
/// Diagonal preconditioner
template <class M, class X, class Y>
struct SeqJacImpl {};
template <class B, class A, class X, class Y>
struct SeqJacImpl<Dune::BCRSMatrix<B,A>,X,Y>
{
using M = Dune::BCRSMatrix<B,A>;
using type = Dune::SeqJac<M,X,Y,1>;
};
template <class B, class A0, class A1, class X, class Y>
struct SeqJacImpl<Dune::Matrix<Dune::BCRSMatrix<B,A0>,A1>,X,Y>
{
using M = Dune::Matrix<Dune::BCRSMatrix<B,A0>,A1>;
using type = Dune::SeqJac<M,X,Y,2>;
};
template <class M, class X, class Y>
using SeqJac = typename SeqJacImpl<M,X,Y>::type;
/// Successive Overrelaxation methods
template <class M, class X, class Y>
struct SeqSORImpl {};
template <class B, class A, class X, class Y>
struct SeqSORImpl<Dune::BCRSMatrix<B,A>,X,Y>
{
using M = Dune::BCRSMatrix<B,A>;
using type = Dune::SeqSOR<M,X,Y,1>;
};
template <class B, class A0, class A1, class X, class Y>
struct SeqSORImpl<Dune::Matrix<Dune::BCRSMatrix<B,A0>,A1>,X,Y>
{
using M = Dune::Matrix<Dune::BCRSMatrix<B,A0>,A1>;
using type = Dune::SeqSOR<M,X,Y,2>;
};
template <class M, class X, class Y>
using SeqSOR = typename SeqSORImpl<M,X,Y>::type;
/// Gauss-Seidel preconditioner
template <class M, class X, class Y>
using SeqGS = SeqSOR<M,X,Y>;
/// Symmetric Successive Overrelaxation methods
template <class M, class X, class Y>
struct SeqSSORImpl {};
template <class B, class A, class X, class Y>
struct SeqSSORImpl<Dune::BCRSMatrix<B,A>,X,Y>
{
using M = Dune::BCRSMatrix<B,A>;
using type = Dune::SeqSSOR<M,X,Y,1>;
};
template <class B, class A0, class A1, class X, class Y>
struct SeqSSORImpl<Dune::Matrix<Dune::BCRSMatrix<B,A0>,A1>,X,Y>
{
using M = Dune::Matrix<Dune::BCRSMatrix<B,A0>,A1>;
using type = Dune::SeqSSOR<M,X,Y,2>;
};
template <class M, class X, class Y>
using SeqSSOR = typename SeqSSORImpl<M,X,Y>::type;
/// Incomplete LU factorization
template <class M, class X, class Y>
struct SeqILUImpl {};
template <class T,int n, class A, class X, class Y>
struct SeqILUImpl<Dune::BCRSMatrix<Dune::FieldMatrix<T,n,n>,A>,X,Y>
{
using M = Dune::BCRSMatrix<Dune::FieldMatrix<T,n,n>,A>;
using type = Dune::SeqILU<M,X,Y>;
};
template <class M, class X, class Y>
using SeqILU = typename SeqILUImpl<M,X,Y>::type;
/// Incomplete LDL factorization
template <class M, class X, class Y>
struct SeqILDLImpl {};
template <class T,int n, class A, class X, class Y>
struct SeqILDLImpl<Dune::BCRSMatrix<Dune::FieldMatrix<T,n,n>,A>,X,Y>
{
using M = Dune::BCRSMatrix<Dune::FieldMatrix<T,n,n>,A>;
using type = Dune::SeqILU<M,X,Y>;
};
template <class M, class X, class Y>
using SeqILDL = typename SeqILDLImpl<M,X,Y>::type;
} // end namespace Preconditioners
} // end namespace AMDiS
......@@ -5,17 +5,20 @@
#include <dune/common/classname.hh>
#include <dune/common/version.hh>
#include <dune/common/ftraits.hh>
#include <amdis/CreatorMap.hpp>
#include <amdis/Environment.hpp>
#include <amdis/Initfile.hpp>
#include <amdis/Output.hpp>
#include <amdis/ProblemStatTraits.hpp>
#include <amdis/common/StaticSize.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/linearalgebra/LinearSolver.hpp>
#include <amdis/linearalgebra/istl/CreatorInterfaces.hpp>
#include <amdis/linearalgebra/istl/ISTLSolver.hpp>
#include <amdis/linearalgebra/istl/Solvers.hpp>
#include <amdis/linearalgebra/istl/SolverWrapper.hpp>
#include <amdis/linearalgebra/istl/Traits.hpp>
#include <amdis/linearalgebra/istl/precompiled/Solvers.hpp>
namespace AMDiS
......@@ -211,9 +214,9 @@ namespace AMDiS
* Note: The reuse parameter is used by SuperLU only, and should be set to false in
* case of multi-threaded applications using the same solver object in multiple threads.
**/
template <class Solver, class Traits>
template <class Traits, class Solver>
struct DirectSolverCreator
: public ISTLSolverCreator<DirectSolverCreator<Solver,Traits>, Traits>
: public ISTLSolverCreator<DirectSolverCreator<Traits,Solver>, Traits>
{
using Super = ISTLSolverCreator<DirectSolverCreator,Traits>;
......@@ -228,7 +231,12 @@ namespace AMDiS
{
test_exit(Dune::SolverCategory::category(comm) == Dune::SolverCategory::sequential,
"Direct solver can be used as sequential solver only.");
return std::make_unique<Solver>(mat, this->info_, reuseVector_);
if constexpr (std::is_constructible_v<Solver,TYPEOF(mat),int,bool>)
return std::make_unique<Solver>(mat, this->info_, reuseVector_);
else {
error_exit("Cannot use the solver {} for this matrix type",Dune::className<Solver>());
return nullptr;
}
}
protected:
......@@ -237,9 +245,9 @@ namespace AMDiS
#if HAVE_SUITESPARSE_CHOLMOD && DUNE_VERSION_GTE(DUNE_ISTL,2,7)
/// Creator for the Choldmod solver
template <class X, class Traits>
struct DirectSolverCreator<Dune::Cholmod<X>,Traits>
: public ISTLSolverCreator<DirectSolverCreator<Dune::Cholmod<X>,Traits>, Traits>
template <class Traits, class X>
struct DirectSolverCreator<Traits,Dune::Cholmod<X>>
: public ISTLSolverCreator<DirectSolverCreator<Traits,Dune::Cholmod<X>>, Traits>
{
using Super = ISTLSolverCreator<DirectSolverCreator,Traits>;
using Super::Super;
......@@ -258,22 +266,6 @@ namespace AMDiS
/// Adds default creators for linear solvers based on `Dune::BCRSMatrix`.
/**
* Adds creators for full-matrix aware solvers.
* - *cg*: conjugate gradient method, \see Dune::CGSolver
* - *pcg*: Generalized preconditioned conjugate gradient solver, \see Dune::GeneralizedPCGSolver
* - *fcg*: Accelerated flexible conjugate gradient method (dune >= 2.7), \see Dune::RestartedFCGSolver
* - *cfcg*: Complete flexible conjugate gradient method (dune >= 2.7), \see Dune::CompleteFCGSolver
* - *bcgs*: stabilized bi-conjugate gradient method, \see Dune::BiCGSTABSolver
* - *minres*: Minimal residul method, \see Dune::MINRESSolver
* - *gmres*: Generalized minimal residual method, \see Dune::RestartedGMResSolver
* - *fgmres*: Flexible Generalized Minimal Residual (FGMRes) method (dune >= 2.7), \see Dune::RestartedFlexibleGMResSolver
* - *umfpack*: external UMFPACK solver, \see Dune::UMFPack
* - *ldl*: external LDL solver, \see Dune::LDL
* - *spqr*: external SQPR solver, \see Dune::SQPR
* - *cholmod*: external Cholmod solver (dune >= 2.7), \see Dune::Cholmod
* - *superlu*: external SuperLU solver, \see Dune::SuperLU
**/
template <class Traits, class Interface>
class DefaultSolverCreators
{
......@@ -281,92 +273,84 @@ namespace AMDiS
using X = typename Traits::X;
using Y = typename Traits::Y;
using FTraits = Dune::FieldTraits<typename M::field_type>;
template <class Solver>
using IterativeSolver = typename IterativeSolverCreator<Solver,Traits>::Creator;
template <class Solver>
using DirectSolver = typename DirectSolverCreator<Solver,Traits>::Creator;
using DirectSolver = typename DirectSolverCreator<Traits,Solver>::Creator;
using Map = CreatorMap<Interface>;
public:
static void init()
{