Commit aa6ed893 authored by Müller, Felix's avatar Müller, Felix Committed by Praetorius, Simon
Browse files

Changed ISTL solver interface to use parallel solver; Added empty communicator...

Changed ISTL solver interface to use parallel solver; Added empty communicator for sequential use of parallel solvers
parent e07d2372
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <amdis/linearalgebra/mtl/DOFVector.hpp> #include <amdis/linearalgebra/mtl/DOFVector.hpp>
#include <amdis/linearalgebra/mtl/ITL_Solver.hpp> #include <amdis/linearalgebra/mtl/ITL_Solver.hpp>
#include <amdis/linearalgebra/mtl/ITL_Preconditioner.hpp> #include <amdis/linearalgebra/mtl/ITL_Preconditioner.hpp>
#include <amdis/linearalgebra/mtl/Traits.hpp>
#elif HAVE_EIGEN #elif HAVE_EIGEN
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
#include <amdis/linearalgebra/eigen/DOFMatrix.hpp> #include <amdis/linearalgebra/eigen/DOFMatrix.hpp>
#include <amdis/linearalgebra/eigen/DOFVector.hpp> #include <amdis/linearalgebra/eigen/DOFVector.hpp>
#include <amdis/linearalgebra/eigen/SolverCreator.hpp> #include <amdis/linearalgebra/eigen/SolverCreator.hpp>
#include <amdis/linearalgebra/eigen/Traits.hpp>
#else // ISTL #else // ISTL
...@@ -25,5 +27,6 @@ ...@@ -25,5 +27,6 @@
#include <amdis/linearalgebra/istl/DOFVector.hpp> #include <amdis/linearalgebra/istl/DOFVector.hpp>
#include <amdis/linearalgebra/istl/ISTL_Solver.hpp> #include <amdis/linearalgebra/istl/ISTL_Solver.hpp>
#include <amdis/linearalgebra/istl/ISTL_Preconditioner.hpp> #include <amdis/linearalgebra/istl/ISTL_Preconditioner.hpp>
#include <amdis/linearalgebra/istl/Traits.hpp>
#endif #endif
\ No newline at end of file
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <dune/common/fvector.hh> #include <dune/common/fvector.hh>
#include <dune/common/fmatrix.hh> #include <dune/common/fmatrix.hh>
#include <dune/grid/common/grid.hh> #include <dune/grid/common/grid.hh>
#include <amdis/AdaptInfo.hpp> #include <amdis/AdaptInfo.hpp>
#include <amdis/CreatorInterface.hpp> #include <amdis/CreatorInterface.hpp>
#include <amdis/CreatorMap.hpp> #include <amdis/CreatorMap.hpp>
...@@ -72,8 +71,13 @@ namespace AMDiS ...@@ -72,8 +71,13 @@ namespace AMDiS
using SystemMatrix = DOFMatrix<GlobalBasis, GlobalBasis, typename Traits::CoefficientType>; using SystemMatrix = DOFMatrix<GlobalBasis, GlobalBasis, typename Traits::CoefficientType>;
using SystemVector = DOFVector<GlobalBasis, typename Traits::CoefficientType>; using SystemVector = DOFVector<GlobalBasis, typename Traits::CoefficientType>;
using LinearSolverTraits = SolverTraits<typename SystemMatrix::BaseMatrix,
typename SystemVector::BaseVector,
typename SystemVector::BaseVector,
GlobalBasis>;
using LinearSolverType = LinearSolverInterface<typename SystemMatrix::BaseMatrix, typename SystemVector::BaseVector>; using LinearSolverType = LinearSolverInterface<LinearSolverTraits>;
using CommInfo = typename LinearSolverTraits::Comm;
public: public:
/** /**
......
...@@ -309,10 +309,10 @@ solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData) ...@@ -309,10 +309,10 @@ solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData)
solverInfo.setCreateMatrixData(createMatrixData); solverInfo.setCreateMatrixData(createMatrixData);
solverInfo.setStoreMatrixData(storeMatrixData); solverInfo.setStoreMatrixData(storeMatrixData);
solution_->compress(); auto commInfo = CommInfo::create(*globalBasis_, name_ + "->solver");
linearSolver_->solve(systemMatrix_->matrix(), solution_->vector(), rhs_->vector(), linearSolver_->solve(systemMatrix_->matrix(), solution_->vector(), rhs_->vector(),
solverInfo); *commInfo, solverInfo);
if (solverInfo.info() > 0) { if (solverInfo.info() > 0) {
msg("solution of discrete system needed {} seconds", t.elapsed()); msg("solution of discrete system needed {} seconds", t.elapsed());
......
...@@ -81,10 +81,23 @@ namespace AMDiS ...@@ -81,10 +81,23 @@ namespace AMDiS
using GridView = typename GlobalBasis::GridView; using GridView = typename GlobalBasis::GridView;
using Grid = typename GridView::Grid; using Grid = typename GridView::Grid;
using Element = typename GridView::template Codim<0>::Entity; using Element = typename GridView::template Codim<0>::Entity;
using EntityIdType = typename Grid::GlobalIdSet::IdType; using EntityIdType = typename Grid::GlobalIdSet::IdType;
using IdType = std::pair<EntityIdType, std::size_t>;
using PartitionType = Dune::PartitionType; using PartitionType = Dune::PartitionType;
struct IdType : std::pair<EntityIdType, std::size_t>
{
using Super = std::pair<EntityIdType, std::size_t>;
IdType(int i = 0) : Super() {};
using Super::Super;
friend std::ostream& operator<<(std::ostream& os, IdType const& id)
{
os << "(" << id.first << "," << id.second << ")";
return os;
}
};
using PreBasis = typename GlobalBasis::PreBasis; using PreBasis = typename GlobalBasis::PreBasis;
using TreePath = typename GlobalBasis::PrefixPath; using TreePath = typename GlobalBasis::PrefixPath;
using NodeIdSet = AMDiS::NodeIdSet<PreBasis, TreePath>; using NodeIdSet = AMDiS::NodeIdSet<PreBasis, TreePath>;
......
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <memory>
#include <string>
namespace AMDiS namespace AMDiS
{ {
...@@ -11,4 +13,30 @@ namespace AMDiS ...@@ -11,4 +13,30 @@ namespace AMDiS
T value; T value;
}; };
template <class Basis>
class DefaultCommunication
{
public:
static std::unique_ptr<DefaultCommunication> create(Basis const& basis, std::string const& prefix)
{
DUNE_UNUSED_PARAMETER(basis);
DUNE_UNUSED_PARAMETER(prefix);
return std::make_unique<DefaultCommunication>();
}
};
/** Base traits class for a linear solver for the system AX=B using an FE space described by a
* dune-functions Basis. This defines the general interface typedefs, all implementations are
* required to provide the typedefs listed here, by e.g. inheriting from this.
*/
template <class A, class X, class B, class Basis>
class SolverTraitsBase
{
public:
using Mat = A;
using Sol = X;
using Rhs = B;
using Comm = DefaultCommunication<Basis>;
};
} // end namespace AMDiS } // end namespace AMDiS
...@@ -20,13 +20,18 @@ namespace AMDiS ...@@ -20,13 +20,18 @@ namespace AMDiS
* solvers where the backend provides an interface, can be assigned * solvers where the backend provides an interface, can be assigned
* by different Runner objects. * by different Runner objects.
**/ **/
template <class Mat, class Sol, class Rhs, class Runner> template <class Traits, class Runner>
class LinearSolver class LinearSolver
: public LinearSolverInterface<Mat, Sol, Rhs> : public LinearSolverInterface<Traits>
{ {
using Self = LinearSolver; using Self = LinearSolver;
using Super = LinearSolverInterface<Mat, Sol, Rhs>; using Super = LinearSolverInterface<Traits>;
using RunnerBase = typename Super::RunnerBase; using RunnerBase = typename Super::RunnerBase;
using Mat = typename Traits::Mat;
using Sol = typename Traits::Sol;
using Rhs = typename Traits::Rhs;
using Comm = typename Traits::Comm;
public: public:
/// A creator to be used instead of the constructor. /// A creator to be used instead of the constructor.
...@@ -52,12 +57,12 @@ namespace AMDiS ...@@ -52,12 +57,12 @@ namespace AMDiS
private: private:
/// Implements \ref LinearSolverInterface::solveSystemImpl() /// Implements \ref LinearSolverInterface::solveSystemImpl()
void solveImpl(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) override void solveImpl(Mat const& A, Sol& x, Rhs const& b, Comm& comm, SolverInfo& solverInfo) override
{ {
Dune::Timer t; Dune::Timer t;
if (solverInfo.doCreateMatrixData()) { if (solverInfo.doCreateMatrixData()) {
// init matrix or wrap block-matrix or ... // init matrix or wrap block-matrix or ...
runner_->init(A); runner_->init(A, comm);
} }
if (solverInfo.info() > 0) if (solverInfo.info() > 0)
......
...@@ -20,11 +20,15 @@ ...@@ -20,11 +20,15 @@
namespace AMDiS namespace AMDiS
{ {
/// Abstract base class for linear solvers /// Abstract base class for linear solvers
template <class Mat, class Sol, class Rhs = Sol> template <class Traits>
class LinearSolverInterface class LinearSolverInterface
{ {
protected: protected:
using RunnerBase = RunnerInterface<Mat, Sol, Rhs>; using RunnerBase = RunnerInterface<Traits>;
using Mat = typename Traits::Mat;
using Sol = typename Traits::Sol;
using Rhs = typename Traits::Rhs;
using Comm = typename Traits::Comm;
public: public:
/// Destructor. /// Destructor.
...@@ -40,9 +44,9 @@ namespace AMDiS ...@@ -40,9 +44,9 @@ namespace AMDiS
* \p x A [block-]vector for the unknown components. * \p x A [block-]vector for the unknown components.
* \p b A [block-]vector for the right-hand side of the linear system. * \p b A [block-]vector for the right-hand side of the linear system.
**/ **/
void solve(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) void solve(Mat const& A, Sol& x, Rhs const& b, Comm& comm, SolverInfo& solverInfo)
{ {
solveImpl(A, x, b, solverInfo); solveImpl(A, x, b, comm, solverInfo);
} }
// return the runner/worker corresponding to this solver (optional) // return the runner/worker corresponding to this solver (optional)
...@@ -50,7 +54,7 @@ namespace AMDiS ...@@ -50,7 +54,7 @@ namespace AMDiS
private: private:
/// main methods that all solvers must implement /// main methods that all solvers must implement
virtual void solveImpl(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) = 0; virtual void solveImpl(Mat const& A, Sol& x, Rhs const& b, Comm& comm, SolverInfo& solverInfo) = 0;
}; };
......
...@@ -5,9 +5,13 @@ ...@@ -5,9 +5,13 @@
namespace AMDiS namespace AMDiS
{ {
/// Interface for Preconditioner types /// Interface for Preconditioner types
template <class Mat, class Sol, class Rhs = Sol> template <class Traits>
struct PreconditionerInterface struct PreconditionerInterface
{ {
using Mat = typename Traits::Mat;
using Sol = typename Traits::Sol;
using Rhs = typename Traits::Rhs;
/// Virtual destructor. /// Virtual destructor.
virtual ~PreconditionerInterface() = default; virtual ~PreconditionerInterface() = default;
......
...@@ -8,18 +8,22 @@ namespace AMDiS ...@@ -8,18 +8,22 @@ namespace AMDiS
class SolverInfo; class SolverInfo;
/// Interface for Runner / Worker types used in solver classes /// Interface for Runner / Worker types used in solver classes
template <class Mat, class Sol, class Rhs = Sol> template <class Traits>
class RunnerInterface class RunnerInterface
{ {
protected: protected:
using PreconBase = PreconditionerInterface<Mat, Sol, Rhs>; using PreconBase = PreconditionerInterface<Traits>;
using Mat = typename Traits::Mat;
using Sol = typename Traits::Sol;
using Rhs = typename Traits::Rhs;
using Comm = typename Traits::Comm;
public: public:
/// virtual destructor /// virtual destructor
virtual ~RunnerInterface() = default; virtual ~RunnerInterface() = default;
/// Is called at the beginning of a solution procedure /// Is called at the beginning of a solution procedure
virtual void init(Mat const& A) = 0; virtual void init(Mat const& A, Comm& comm) = 0;
/// Is called at the end of a solution procedure /// Is called at the end of a solution procedure
virtual void exit() = 0; virtual void exit() = 0;
......
...@@ -7,4 +7,5 @@ install(FILES ...@@ -7,4 +7,5 @@ install(FILES
PreconConfig.hpp PreconConfig.hpp
SolverConfig.hpp SolverConfig.hpp
SolverCreator.hpp SolverCreator.hpp
Traits.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/linearalgebra/eigen) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/linearalgebra/eigen)
...@@ -14,13 +14,17 @@ namespace AMDiS ...@@ -14,13 +14,17 @@ namespace AMDiS
* \class AMDiS::DirectRunner * \class AMDiS::DirectRunner
* \brief \implements RunnerInterface for the (external) direct solvers * \brief \implements RunnerInterface for the (external) direct solvers
*/ */
template <template <class> class Solver, class Matrix, class VectorX, class VectorB> template <template <class> class Solver, class Traits>
class DirectRunner class DirectRunner
: public RunnerInterface<Matrix, VectorX, VectorB> : public RunnerInterface<Traits>
{ {
protected: protected:
using Super = RunnerInterface<Matrix, VectorX, VectorB>; using Super = RunnerInterface<Traits>;
using EigenSolver = Solver<Matrix>; using Mat = typename Traits::Mat;
using Sol = typename Traits::Sol;
using Rhs = typename Traits::Rhs;
using Comm = typename Traits::Comm;
using EigenSolver = Solver<Mat>;
public: public:
/// Constructor. /// Constructor.
...@@ -31,9 +35,11 @@ namespace AMDiS ...@@ -31,9 +35,11 @@ namespace AMDiS
Parameters::get(prefix + "->reuse pattern", reusePattern_); Parameters::get(prefix + "->reuse pattern", reusePattern_);
} }
/// Implementes \ref RunnerInterface::init() /// Implements \ref RunnerInterface::init()
void init(Matrix const& A) override void init(Mat const& A, Comm& comm) override
{ {
DUNE_UNUSED_PARAMETER(comm);
if (!reusePattern_ || !initialized_) { if (!reusePattern_ || !initialized_) {
solver_.analyzePattern(A); solver_.analyzePattern(A);
initialized_ = true; initialized_ = true;
...@@ -45,16 +51,17 @@ namespace AMDiS ...@@ -45,16 +51,17 @@ namespace AMDiS
} }
/// Implementes \ref RunnerInterface::exit() /// Implements \ref RunnerInterface::exit()
void exit() override {} void exit() override {}
/// Implementes \ref RunnerInterface::solve() /// Implements \ref RunnerInterface::solve()
int solve(Matrix const& A, VectorX& x, VectorB const& b, int solve(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) override
SolverInfo& solverInfo) override
{ {
DUNE_UNUSED_PARAMETER(A);
x = solver_.solve(b); x = solver_.solve(b);
auto r = VectorB(b); auto r = Rhs(b);
if (x.norm() != 0) if (x.norm() != 0)
r -= A * x; r -= A * x;
......
...@@ -9,12 +9,16 @@ ...@@ -9,12 +9,16 @@
namespace AMDiS namespace AMDiS
{ {
template <class IterativeSolver, class Matrix, class VectorX, class VectorB> template <class IterativeSolver, class Traits>
class IterativeRunner class IterativeRunner
: public RunnerInterface<Matrix, VectorX, VectorB> : public RunnerInterface<Traits>
{ {
using SolverCfg = SolverConfig<IterativeSolver>; using SolverCfg = SolverConfig<IterativeSolver>;
using PreconCfg = PreconConfig<typename IterativeSolver::Preconditioner>; using PreconCfg = PreconConfig<typename IterativeSolver::Preconditioner>;
using Mat = typename Traits::Mat;
using Sol = typename Traits::Sol;
using Rhs = typename Traits::Rhs;
using Comm = typename Traits::Comm;
public: public:
IterativeRunner(std::string const& prefix) IterativeRunner(std::string const& prefix)
...@@ -26,9 +30,11 @@ namespace AMDiS ...@@ -26,9 +30,11 @@ namespace AMDiS
} }
/// Implementes \ref RunnerInterface::init() /// Implements \ref RunnerInterface::init()
void init(Matrix const& A) override void init(Mat const& A, Comm& comm) override
{ {
DUNE_UNUSED_PARAMETER(comm);
if (!reusePattern_ || !initialized_) { if (!reusePattern_ || !initialized_) {
solver_.analyzePattern(A); solver_.analyzePattern(A);
initialized_ = true; initialized_ = true;
...@@ -39,17 +45,18 @@ namespace AMDiS ...@@ -39,17 +45,18 @@ namespace AMDiS
"Error in solver.compute(matrix)"); "Error in solver.compute(matrix)");
} }
/// Implementes \ref RunnerInterface::exit() /// Implements \ref RunnerInterface::exit()
void exit() override {} void exit() override {}
/// Implementes \ref RunnerInterface::solve() /// Implements \ref RunnerInterface::solve()
int solve(Matrix const& A, VectorX& x, VectorB const& b, int solve(Mat const& A, Sol& x, Rhs const& b, SolverInfo& solverInfo) override
SolverInfo& solverInfo) override
{ {
DUNE_UNUSED_PARAMETER(A);
solver_.setTolerance(solverInfo.relTolerance()); solver_.setTolerance(solverInfo.relTolerance());
x = solver_.solveWithGuess(b, x); x = solver_.solveWithGuess(b, x);
auto r = VectorB(b); auto r = Rhs(b);
if (x.norm() != 0) if (x.norm() != 0)
r -= A * x; r -= A * x;
......
...@@ -11,24 +11,27 @@ ...@@ -11,24 +11,27 @@
#include <amdis/CreatorMap.hpp> #include <amdis/CreatorMap.hpp>
#include <amdis/Initfile.hpp> #include <amdis/Initfile.hpp>
#include <amdis/Output.hpp>
#include <amdis/linearalgebra/LinearSolver.hpp> #include <amdis/linearalgebra/LinearSolver.hpp>
#include <amdis/linearalgebra/eigen/DirectRunner.hpp> #include <amdis/linearalgebra/eigen/DirectRunner.hpp>
#include <amdis/linearalgebra/eigen/IterativeRunner.hpp> #include <amdis/linearalgebra/eigen/IterativeRunner.hpp>
#include <amdis/linearalgebra/eigen/Traits.hpp>
namespace AMDiS namespace AMDiS
{ {
template <class Matrix, class VectorX, class VectorB, template <class> class IterativeSolver> template <class Traits, template <class> class IterativeSolver>
struct IterativeSolverCreator struct IterativeSolverCreator
: public CreatorInterfaceName<LinearSolverInterface<Matrix, VectorX, VectorB>> : public CreatorInterfaceName<LinearSolverInterface<Traits>>
{ {
template <class Precon> template <class Precon>
using SolverCreator using SolverCreator
= typename LinearSolver<Matrix, VectorX, VectorB, = typename LinearSolver<Traits,
IterativeRunner<IterativeSolver<Precon>, Matrix, VectorX, VectorB>>::Creator; IterativeRunner<IterativeSolver<Precon>, Traits>>::Creator;
using SolverBase = LinearSolverInterface<Matrix, VectorX, VectorB>; using SolverBase = LinearSolverInterface<Traits>;
using Scalar = typename Matrix::Scalar; using Mat = typename Traits::Mat;
using Scalar = typename Mat::Scalar;
std::unique_ptr<SolverBase> createWithString(std::string prefix) override std::unique_ptr<SolverBase> createWithString(std::string prefix) override
{ {
...@@ -68,17 +71,16 @@ namespace AMDiS ...@@ -68,17 +71,16 @@ namespace AMDiS
Parameters::get(prefix + "->precon->ordering", ordering); Parameters::get(prefix + "->precon->ordering", ordering);
if (ordering == "amd") { if (ordering == "amd") {
using AMD = Eigen::AMDOrdering<typename Matrix::StorageIndex>; using AMD = Eigen::AMDOrdering<typename Mat::StorageIndex>;
return IncompleteCholesky<AMD>{}.createWithString(prefix); return IncompleteCholesky<AMD>{}.createWithString(prefix);
} }
else { else {
using NATURAL = Eigen::NaturalOrdering<typename Matrix::StorageIndex>; using NATURAL = Eigen::NaturalOrdering<typename Mat::StorageIndex>;
return IncompleteCholesky<NATURAL>{}.createWithString(prefix); return IncompleteCholesky<NATURAL>{}.createWithString(prefix);
} }
} }
}; };
/// Adds default creators for linear solvers based on `Eigen::SparseMatrix`. /// Adds default creators for linear solvers based on `Eigen::SparseMatrix`.
/** /**
* Adds creators for full-matrix aware solvers. * Adds creators for full-matrix aware solvers.
...@@ -90,36 +92,37 @@ namespace AMDiS ...@@ -90,36 +92,37 @@ namespace AMDiS
* - *umfpack*: external UMFPACK solver, \see Eigen::UmfPackLU * - *umfpack*: external UMFPACK solver, \see Eigen::UmfPackLU
* - *superlu*: external SparseLU solver, \see Eigen::SparseLU * - *superlu*: external SparseLU solver, \see Eigen::SparseLU
**/ **/
template <class T, int O, class VectorX, class VectorB> template <class Traits>
class DefaultCreators<LinearSolverInterface<Eigen::SparseMatrix<T,O>, VectorX, VectorB>> class DefaultCreators< LinearSolverInterface<Traits> >
{ {
using Matrix = Eigen::SparseMatrix<T,O>; using Mat = typename Traits::Mat;
using SolverBase = LinearSolverInterface<Matrix, VectorX, VectorB>;
using SolverBase = LinearSolverInterface<Traits>;