Commit 4a878787 authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

ISTL solvers and data structured usable

parent f6447413
...@@ -15,7 +15,7 @@ using namespace AMDiS; ...@@ -15,7 +15,7 @@ using namespace AMDiS;
using namespace Dune::Indices; using namespace Dune::Indices;
// 1 component with polynomial degree 1 // 1 component with polynomial degree 1
using Param = YaspGridBasis<AMDIS_DIM, 1>; using Param = YaspGridBasis<AMDIS_DIM, 2>;
using ElliptProblem = ProblemStat<Param>; using ElliptProblem = ProblemStat<Param>;
int main(int argc, char** argv) int main(int argc, char** argv)
......
...@@ -3,10 +3,10 @@ elliptMesh->global refinements: 0 ...@@ -3,10 +3,10 @@ elliptMesh->global refinements: 0
ellipt->mesh: elliptMesh ellipt->mesh: elliptMesh
ellipt->solver->name: bicgstab ellipt->solver->name: bicgstab
ellipt->solver->max iteration: 1000 ellipt->solver->max iteration: 10000
ellipt->solver->relative tolerance: 1.e-8 ellipt->solver->relative tolerance: 1.e-10
ellipt->solver->info: 10 ellipt->solver->info: 1
ellipt->solver->left precon: diag ellipt->solver->left precon: ilu
ellipt->solver->right precon: no ellipt->solver->right precon: no
ellipt->output[0]->filename: ellipt.2d ellipt->output[0]->filename: ellipt.2d
......
...@@ -80,10 +80,12 @@ int main(int argc, char** argv) ...@@ -80,10 +80,12 @@ int main(int argc, char** argv)
// assemble and solve system // assemble and solve system
prob.buildAfterCoarsen(adaptInfo, Flag(0)); prob.buildAfterCoarsen(adaptInfo, Flag(0));
#ifdef DEBUG_MTL
// write matrix to file // write matrix to file
mtl::io::matrix_market_ostream out("matrix_stokes0.mtx"); mtl::io::matrix_market_ostream out("matrix_stokes0.mtx");
out << prob.getSystemMatrix().matrix(); out << prob.getSystemMatrix().matrix();
std::cout << prob.getSystemMatrix().matrix() << '\n'; std::cout << prob.getSystemMatrix().matrix() << '\n';
#endif
prob.solve(adaptInfo); prob.solve(adaptInfo);
......
...@@ -81,10 +81,12 @@ int main(int argc, char** argv) ...@@ -81,10 +81,12 @@ int main(int argc, char** argv)
// assemble and solve system // assemble and solve system
prob.buildAfterCoarsen(adaptInfo, Flag(0)); prob.buildAfterCoarsen(adaptInfo, Flag(0));
#ifdef DEBUG_MTL
// write matrix to file // write matrix to file
mtl::io::matrix_market_ostream out("matrix_stokes1.mtx"); mtl::io::matrix_market_ostream out("matrix_stokes1.mtx");
out << prob.getSystemMatrix().matrix(); out << prob.getSystemMatrix().matrix();
std::cout << prob.getSystemMatrix().matrix() << '\n'; std::cout << prob.getSystemMatrix().matrix() << '\n';
#endif
prob.solve(adaptInfo); prob.solve(adaptInfo);
......
...@@ -42,6 +42,7 @@ int main(int argc, char** argv) ...@@ -42,6 +42,7 @@ int main(int argc, char** argv)
prob.buildAfterCoarsen(adaptInfo, Flag(0)); prob.buildAfterCoarsen(adaptInfo, Flag(0));
#ifdef DEBUG_MTL
// write matrix to file // write matrix to file
if (Parameters::get<int>("elliptMesh->global refinements").value_or(0) < 4) { if (Parameters::get<int>("elliptMesh->global refinements").value_or(0) < 4) {
mtl::io::matrix_market_ostream out("matrix.mtx"); mtl::io::matrix_market_ostream out("matrix.mtx");
...@@ -49,6 +50,7 @@ int main(int argc, char** argv) ...@@ -49,6 +50,7 @@ int main(int argc, char** argv)
std::cout << prob.getSystemMatrix().matrix() << '\n'; std::cout << prob.getSystemMatrix().matrix() << '\n';
} }
#endif
prob.solve(adaptInfo); prob.solve(adaptInfo);
prob.writeFiles(adaptInfo, true); prob.writeFiles(adaptInfo, true);
......
...@@ -24,8 +24,8 @@ void Assembler<Traits>::assemble( ...@@ -24,8 +24,8 @@ void Assembler<Traits>::assemble(
// 2. create a local matrix and vector // 2. create a local matrix and vector
std::size_t localSize = localView.maxSize(); std::size_t localSize = localView.maxSize();
mtl::mat::dense2D<typename SystemMatrixType::value_type> elementMatrix(localSize, localSize); mtl::mat::dense2D<double> elementMatrix(localSize, localSize);
mtl::vec::dense_vector<typename SystemVectorType::value_type> elementVector(localSize); mtl::vec::dense_vector<double> elementVector(localSize);
// 3. traverse grid and assemble operators on the elements // 3. traverse grid and assemble operators on the elements
for (auto const& element : elements(globalBasis_.gridView())) for (auto const& element : elements(globalBasis_.gridView()))
......
#pragma once #pragma once
#include <amdis/linear_algebra/LinearSolverInterface.hpp> #include <amdis/linear_algebra/LinearSolver.hpp>
#include <amdis/linear_algebra/SolverInfo.hpp> #include <amdis/linear_algebra/SolverInfo.hpp>
#if HAVE_MTL
#include <amdis/linear_algebra/mtl/DOFVector.hpp> #include <amdis/linear_algebra/mtl/DOFVector.hpp>
#include <amdis/linear_algebra/mtl/DOFMatrix.hpp> #include <amdis/linear_algebra/mtl/DOFMatrix.hpp>
#include <amdis/linear_algebra/mtl/LinearSolver.hpp>
#include <amdis/linear_algebra/mtl/ITL_Solver.hpp> #include <amdis/linear_algebra/mtl/ITL_Solver.hpp>
#include <amdis/linear_algebra/mtl/ITL_Preconditioner.hpp>
#else
#include <amdis/linear_algebra/istl/DOFVector.hpp>
#include <amdis/linear_algebra/istl/DOFMatrix.hpp>
#include <amdis/linear_algebra/istl/ISTL_Solver.hpp>
#include <amdis/linear_algebra/istl/ISTL_Preconditioner.hpp>
#endif
\ No newline at end of file
#pragma once
#include <cstddef>
namespace AMDiS
{
template <class T>
struct Triplet
{
std::size_t row, cols;
T value;
};
} // end namespace AMDiS
#pragma once
#include <algorithm>
#include <memory>
#include <string>
#include <boost/numeric/mtl/vector/dense_vector.hpp>
#include <amdis/Output.hpp>
#include <amdis/common/ClonablePtr.hpp>
#include <amdis/common/ScalarTypes.hpp>
#include <amdis/linear_algebra/DOFVectorInterface.hpp>
#include <amdis/utility/MultiIndex.hpp>
namespace AMDiS
{
/// The basic container that stores a base vector and a corresponding basis
template <class BasisType>
class DOFVectorBase
: public DOFVectorInterface
{
using Self = DOFVectorBase;
public:
/// The type of the \ref basis
using Basis = BasisType;
/// The index/size - type
using size_type = typename BasisType::size_type;
/// Constructor. Constructs new BaseVector.
DOFVectorBase(BasisType const& basis)
: basis_(&basis)
{}
/// Return the basis \ref basis_ of the vector
Basis const& basis() const
{
return *basis_;
}
/// Return the size of the \ref basis
size_type size() const
{
return basis_->dimension();
}
private:
/// The finite element space / basis associated with the data vector
Basis const* basis_;
};
} // end namespace AMDiS
...@@ -14,18 +14,18 @@ namespace AMDiS ...@@ -14,18 +14,18 @@ namespace AMDiS
/** \ingroup Solver /** \ingroup Solver
* *
* \brief * \brief
* Wrapper class for various MTL4 solvers. These solvers * Wrapper class for various solvers. These solvers
* are parametrized by MatrixType and VectorType. The different * are parametrized by MatrixType and VectorType. The different
* algorithms, like krylov subspace methods or other external * algorithms, like krylov subspace methods or other external
* solvers where MTL4 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 Matrix, class Vector, class Runner> template <class Matrix, class VectorX, class VectorB, class Runner>
class LinearSolver class LinearSolver
: public LinearSolverInterface<Matrix, Vector, Vector> : public LinearSolverInterface<Matrix, VectorX, VectorB>
{ {
using Self = LinearSolver; using Self = LinearSolver;
using Super = LinearSolverInterface<Matrix, Vector, Vector>; using Super = LinearSolverInterface<Matrix, VectorX, VectorB>;
using RunnerBase = typename Super::RunnerBase; using RunnerBase = typename Super::RunnerBase;
public: public:
...@@ -44,15 +44,15 @@ namespace AMDiS ...@@ -44,15 +44,15 @@ namespace AMDiS
: runner_(std::make_shared<Runner>(prefix)) : runner_(std::make_shared<Runner>(prefix))
{} {}
/// Implements \ref LinearSolverInterface::getRunner() /// Implements \ref LinearSolverInterface::runner()
virtual std::shared_ptr<RunnerBase> getRunner() override virtual std::shared_ptr<RunnerBase> runner() override
{ {
return runner_; return runner_;
} }
private: private:
/// Implements \ref LinearSolverInterface::solveSystemImpl() /// Implements \ref LinearSolverInterface::solveSystemImpl()
virtual void solveImpl(Matrix const& A, Vector& x, Vector const& b, virtual void solveImpl(Matrix const& A, VectorX& x, VectorB const& b,
SolverInfo& solverInfo) override SolverInfo& solverInfo) override
{ {
Dune::Timer t; Dune::Timer t;
...@@ -61,9 +61,8 @@ namespace AMDiS ...@@ -61,9 +61,8 @@ namespace AMDiS
runner_->init(A); runner_->init(A);
} }
if (solverInfo.getInfo() > 0) { if (solverInfo.getInfo() > 0)
msg("fill MTL4 matrix needed ", t.elapsed(), " seconds"); msg("fill matrix needed ", t.elapsed(), " seconds");
}
int error = runner_->solve(A, x, b, solverInfo); int error = runner_->solve(A, x, b, solverInfo);
solverInfo.setError(error); solverInfo.setError(error);
......
...@@ -48,7 +48,7 @@ namespace AMDiS ...@@ -48,7 +48,7 @@ namespace AMDiS
} }
// return the runner/worker corresponding to this solver (optional) // return the runner/worker corresponding to this solver (optional)
virtual std::shared_ptr<RunnerBase> getRunner() { return {}; }; virtual std::shared_ptr<RunnerBase> runner() { return {}; };
private: private:
/// main methods that all solvers must implement /// main methods that all solvers must implement
......
...@@ -11,7 +11,4 @@ install(FILES ...@@ -11,7 +11,4 @@ install(FILES
ISTLRunner.hpp ISTLRunner.hpp
LinearSolver.hpp LinearSolver.hpp
Preconditioner.hpp Preconditioner.hpp
SystemMatrix.hpp
SystemVector.hpp
UmfpackRunner.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/linear_algebra/istl) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/linear_algebra/istl)
...@@ -8,111 +8,126 @@ ...@@ -8,111 +8,126 @@
#include <amdis/Output.hpp> #include <amdis/Output.hpp>
#include <amdis/common/ClonablePtr.hpp> #include <amdis/common/ClonablePtr.hpp>
#include <amdis/linear_algebra/DOFMatrixBase.hpp>
#include <amdis/utility/MultiIndex.hpp>
namespace AMDiS namespace AMDiS
{ {
template <class RowFeSpaceType, class ColFeSpaceType, template <class T, class = void>
class ValueType = Dune::FieldMatrix<double,1,1>> struct BlockMatrixType
{
using type = Dune::FieldMatrix<T,1,1>;
};
template <class T>
struct BlockMatrixType<T, typename T::field_type>
{
using type = T;
};
template <class RowBasisType, class ColBasisType,
class ValueType = double>
class DOFMatrix class DOFMatrix
{ {
public: public:
using RowFeSpace = RowFeSpaceType; /// The type of the finite element space / basis of the row
using ColFeSpace = ColFeSpaceType; using RowBasis = RowBasisType;
using BaseMatrix = Dune::BCRSMatrix<ValueType>;
/// The type of the finite element space / basis of the column
using ColBasis = ColBasisType;
using size_type = typename RowFeSpaceType::size_type; /// The type of the elements of the DOFMatrix
using field_type = typename ValueType::field_type; using value_type = typename BlockMatrixType<ValueType>::type;
using value_type = ValueType; /// The matrix type of the underlying base matrix
using BaseMatrix = Dune::BCRSMatrix<value_type>;
/// The index/size - type
using size_type = typename BaseMatrix::size_type;
public:
/// Constructor. Constructs new BaseVector. /// Constructor. Constructs new BaseVector.
DOFMatrix(RowFeSpace const& rowFeSpace, ColFeSpace const& colFeSpace, std::string name) DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis)
: rowFeSpace(rowFeSpace) : rowBasis_(&rowBasis)
, colFeSpace(colFeSpace) , colBasis_(&colBasis)
, name(name) , matrix_(ClonablePtr<BaseMatrix>::make())
, matrix(ClonablePtr<BaseMatrix>::make())
{} {}
/// Constructor. Takes pointer of data-vector. /// Constructor. Takes reference to a base matrix.
DOFMatrix(RowFeSpace const& rowFeSpace, ColFeSpace const& colFeSpace, std::string name, DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis, BaseMatrix& matrix)
BaseMatrix& matrix_ref) : rowBasis_(&rowBasis)
: rowFeSpace(rowFeSpace) , colBasis_(&colBasis)
, colFeSpace(colFeSpace) , matrix_(matrix)
, name(name)
, matrix(matrix_ref)
{} {}
/// Return the row-basis \ref rowFeSpace of the matrix /// Return the row-basis \ref rowBasis of the matrix
RowFeSpace const& getRowFeSpace() const RowBasis const& rowBasis() const
{ {
return rowFeSpace; return *rowBasis_;
} }
/// Return the col-basis \ref colFeSpace of the matrix /// Return the col-basis \ref colBasis of the matrix
ColFeSpace const& getColFeSpace() const ColBasis const& colBasis() const
{ {
return colFeSpace; return *colBasis_;
} }
/// Return the data-vector \ref vector /// Return the data-vector \ref vector
BaseMatrix const& getMatrix() const BaseMatrix const& matrix() const
{ {
return *matrix; return *matrix_;
} }
/// Return the data-vector \ref vector /// Return the data-vector \ref vector
BaseMatrix& getMatrix() BaseMatrix& matrix()
{ {
return *matrix; return *matrix_;
} }
/// Return the size of the \ref feSpace /// Return the size of the \ref feSpace
size_type N() const size_type rows() const
{
return rowFeSpace.size();
}
size_type M() const
{ {
return colFeSpace.size(); return rowBasis_->size();
} }
/// Return the \ref name of this vector size_type cols() const
std::string getName() const
{ {
return name; return colBasis_->size();
} }
/// Access the entry \p i of the \ref vector with read-access. /// Access the entry \p i of the \ref vector with read-access.
value_type const& operator()(size_type r, size_type c) const template <class Index>
value_type const& operator()(Index row, Index col) const
{ {
test_exit_dbg( initialized, "Occupation pattern not initialized!"); size_type r = flatMultiIndex(row), c = flatMultiIndex(col);
test_exit_dbg( r < N() && c < M() , test_exit_dbg( initialized_, "Occupation pattern not initialized!");
"Indices out of range [0,", N(), ")x[0,", M(), ")" ); test_exit_dbg( r < rows() && c < cols() ,
return (*matrix)[r][c]; "Indices out of range [0,", rows(), ")x[0,", cols(), ")" );
return (*matrix_)[r][c];
} }
/// Access the entry \p i of the \ref vector with write-access. /// Access the entry \p i of the \ref vector with write-access.
value_type& operator()(size_type r, size_type c) template <class Index>
value_type& operator()(Index row, Index col)
{ {
test_exit_dbg( initialized, "Occupation pattern not initialized!"); size_type r = flatMultiIndex(row), c = flatMultiIndex(col);
test_exit_dbg( r < N() && c < M() , test_exit_dbg( initialized_, "Occupation pattern not initialized!");
"Indices out of range [0,", N(), ")x[0,", M(), ")" ); test_exit_dbg( r < rows() && c < cols() ,
return (*matrix)[r][c]; "Indices out of range [0,", rows(), ")x[0,", cols(), ")" );
return (*matrix_)[r][c];
} }
/// create occupation pattern and apply it to the matrix /// create occupation pattern and apply it to the matrix
void init() void init(bool prepareForInsertion)
{ {
occupationPattern.resize(rowFeSpace.size(), colFeSpace.size()); occupationPattern_.resize(rowBasis_->size(), colBasis_->size());
auto meshView = rowFeSpace.gridView();
// A loop over all elements of the grid // A loop over all elements of the grid
auto rowLocalView = rowFeSpace.localView(); auto rowLocalView = rowBasis_->localView();
auto colLocalView = colFeSpace.localView(); auto colLocalView = colBasis_->localView();
for (const auto& element : elements(meshView)) { for (const auto& element : elements(rowBasis_->gridView())) {
rowLocalView.bind(element); rowLocalView.bind(element);
colLocalView.bind(element); colLocalView.bind(element);
...@@ -122,54 +137,50 @@ namespace AMDiS ...@@ -122,54 +137,50 @@ namespace AMDiS
for (std::size_t j = 0; j < colLocalView.size(); ++j) { for (std::size_t j = 0; j < colLocalView.size(); ++j) {
// The global index of the j-th vertex of the element // The global index of the j-th vertex of the element
auto col = colLocalView.index(j); auto col = colLocalView.index(j);
occupationPattern.add(row, col); occupationPattern_.add(row, col);
} }
} }
} }
occupationPattern.exportIdx(*matrix); occupationPattern_.exportIdx(*matrix_);
initialized = true; initialized_ = true;
} }
void finish() void finish()
{ {
initialized = false; initialized_ = false;
} }
std::size_t nnz() std::size_t nnz() const
{ {
return matrix->nonzeroes(); return matrix_->nonzeroes();
} }
auto clearDirichletRows(std::vector<char> const& dirichletNodes, bool apply) auto applyDirichletBC(std::vector<char> const& dirichletNodes)
{ {
// loop over the matrix rows // loop over the matrix rows
for (std::size_t i = 0; i < matrix->N(); ++i) { for (std::size_t i = 0; i < matrix_->N(); ++i) {
if (dirichletNodes[i]) { if (dirichletNodes[i]) {
auto cIt = (*matrix)[i].begin(); auto cIt = (*matrix_)[i].begin();
auto cEndIt = (*matrix)[i].end(); auto cEndIt = (*matrix_)[i].end();
// loop over nonzero matrix entries in current row // loop over nonzero matrix entries in current row
for (; cIt != cEndIt; ++cIt) for (; cIt != cEndIt; ++cIt)
*cIt = (apply && i == cIt.index() ? 1 : 0); *cIt = (i == cIt.index() ? 1 : 0);
} }
} }
std::vector<std::map<size_t,value_type>> columns; // symmetric dbc not yet implemented std::list<Triplet<value_type>> columns; // symmetric dbc not yet implemented
return columns; return columns;
}