Commit 7bd6ff1c authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'issue/cleanup_dofvector' into 'develop'

Issue/cleanup dofvector

See merge request !29
parents 9d6a1e4c 55a910fd
Pipeline #1231 failed with stage
in 4 seconds
......@@ -14,7 +14,7 @@ namespace AMDiS
public:
/// virtual destructor
virtual ~RunnerInterface() {}
virtual ~RunnerInterface() = default;
/// Is called at the beginning of a solution procedure
virtual void init(Matrix const& A) = 0;
......@@ -34,8 +34,8 @@ namespace AMDiS
return 0;
}
virtual std::shared_ptr<PreconBase> getLeftPrecon() { return {}; }
virtual std::shared_ptr<PreconBase> getRightPrecon() { return {}; }
virtual std::shared_ptr<PreconBase> leftPrecon() { return {}; }
virtual std::shared_ptr<PreconBase> rightPrecon() { return {}; }
};
} // end namespace AMDiS
......@@ -4,14 +4,11 @@
#)
install(FILES
DirectRunner.hpp
DOFMatrix.hpp
DOFVector.hpp
Fwd.hpp
ISTL_Preconditioner.hpp
ISTL_Solver.hpp
ISTLRunner.hpp
LinearSolver.hpp
Preconditioner.hpp
SystemMatrix.hpp
SystemVector.hpp
UmfpackRunner.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/linear_algebra/istl)
#pragma once
#include <list>
#include <string>
#include <memory>
......@@ -7,112 +8,73 @@
#include <dune/istl/matrixindexset.hh>
#include <amdis/Output.hpp>
#include <amdis/common/ClonablePtr.hpp>
#include <amdis/linear_algebra/Common.hpp>
#include <amdis/linear_algebra/DOFMatrixBase.hpp>
#include <amdis/utility/MultiIndex.hpp>
namespace AMDiS
{
template <class RowFeSpaceType, class ColFeSpaceType,
class ValueType = Dune::FieldMatrix<double,1,1>>
class DOFMatrix
template <class T, class = void>
struct BlockMatrixType
{
using type = Dune::FieldMatrix<T,1,1>;
};
template <class T>
struct BlockMatrixType<T, typename T::field_type>
{
using type = T;
};
template <class ValueType>
class IstlMatrix
{
public:
using RowFeSpace = RowFeSpaceType;
using ColFeSpace = ColFeSpaceType;
using BaseMatrix = Dune::BCRSMatrix<ValueType>;
/// The type of the elements of the DOFMatrix
using value_type = typename BlockMatrixType<ValueType>::type;
using size_type = typename RowFeSpaceType::size_type;
using field_type = typename ValueType::field_type;
/// The matrix type of the underlying base matrix
using BaseMatrix = Dune::BCRSMatrix<value_type>;
using value_type = ValueType;
/// The index/size - type
using size_type = typename BaseMatrix::size_type;
public:
/// Constructor. Constructs new BaseVector.
DOFMatrix(RowFeSpace const& rowFeSpace, ColFeSpace const& colFeSpace, std::string name)
: rowFeSpace(rowFeSpace)
, colFeSpace(colFeSpace)
, name(name)
, matrix(ClonablePtr<BaseMatrix>::make())
{}
/// Constructor. Takes pointer of data-vector.
DOFMatrix(RowFeSpace const& rowFeSpace, ColFeSpace const& colFeSpace, std::string name,
BaseMatrix& matrix_ref)
: rowFeSpace(rowFeSpace)
, colFeSpace(colFeSpace)
, name(name)
, matrix(matrix_ref)
{}
/// Return the row-basis \ref rowFeSpace of the matrix
RowFeSpace const& getRowFeSpace() const
{
return rowFeSpace;
}
/// Return the col-basis \ref colFeSpace of the matrix
ColFeSpace const& getColFeSpace() const
{
return colFeSpace;
}
IstlMatrix() = default;
/// Return the data-vector \ref vector
BaseMatrix const& getMatrix() const
BaseMatrix const& matrix() const
{
return *matrix;
return matrix_;
}
/// Return the data-vector \ref vector
BaseMatrix& getMatrix()
{
return *matrix;
}
/// Return the size of the \ref feSpace
size_type N() const
{
return rowFeSpace.size();
}
size_type M() const
{
return colFeSpace.size();
}
/// Return the \ref name of this vector
std::string getName() const
BaseMatrix& matrix()
{
return name;
return matrix_;
}
/// Access the entry \p i of the \ref vector with read-access.
value_type const& operator()(size_type r, size_type c) const
/// Insert a single value into the matrix (add to existing value)
void insert(size_type r, size_type c, value_type const& value)
{
test_exit_dbg( initialized, "Occupation pattern not initialized!");
test_exit_dbg( r < N() && c < M() ,
"Indices out of range [0,", N(), ")x[0,", M(), ")" );
return (*matrix)[r][c];
}
/// Access the entry \p i of the \ref vector with write-access.
value_type& operator()(size_type r, size_type c)
{
test_exit_dbg( initialized, "Occupation pattern not initialized!");
test_exit_dbg( r < N() && c < M() ,
"Indices out of range [0,", N(), ")x[0,", M(), ")" );
return (*matrix)[r][c];
test_exit_dbg( initialized_, "Occupation pattern not initialized!");
test_exit_dbg( r < matrix_.N() && c < matrix_.M() ,
"Indices out of range [0,", matrix_.N(), ")x[0,", matrix_.M(), ")" );
matrix_[r][c] += value;
}
/// create occupation pattern and apply it to the matrix
void init()
template <class RowBasis, class ColBasis>
void init(RowBasis const& rowBasis, ColBasis const& colBasis,
bool prepareForInsertion)
{
occupationPattern.resize(rowFeSpace.size(), colFeSpace.size());
auto meshView = rowFeSpace.gridView();
// A loop over all elements of the grid
auto rowLocalView = rowFeSpace.localView();
auto colLocalView = colFeSpace.localView();
auto occupationPattern = Dune::MatrixIndexSet{rowBasis.dimension(), colBasis.dimension()};
for (const auto& element : elements(meshView)) {
auto rowLocalView = rowBasis.localView();
auto colLocalView = colBasis.localView();
for (const auto& element : elements(rowBasis.gridView())) {
rowLocalView.bind(element);
colLocalView.bind(element);
......@@ -126,50 +88,44 @@ namespace AMDiS
}
}
}
occupationPattern.exportIdx(*matrix);
occupationPattern.exportIdx(matrix_);
initialized = true;
initialized_ = true;
}
void finish()
{
initialized = false;
initialized_ = false;
}
std::size_t getNnz()
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
for (std::size_t i = 0; i < matrix->N(); ++i) {
for (std::size_t i = 0; i < matrix_.N(); ++i) {
if (dirichletNodes[i]) {
auto cIt = (*matrix)[i].begin();
auto cEndIt = (*matrix)[i].end();
auto cIt = matrix_[i].begin();
auto cEndIt = matrix_[i].end();
// loop over nonzero matrix entries in current row
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
return columns;
return std::list<Triplet<value_type>>{};
}
private:
RowFeSpace const& rowFeSpace;
ColFeSpace const& colFeSpace;
std::string name;
BaseMatrix matrix_;
ClonablePtr<BaseMatrix> matrix;
Dune::MatrixIndexSet occupationPattern;
bool initialized = false;
// friend class declarations
template <class, class, class> friend class SystemMatrix;
bool initialized_ = false;
};
template <class RowBasisType, class ColBasisType, class ValueType = double>
using DOFMatrix = DOFMatrixBase<RowBasisType, ColBasisType, IstlMatrix<ValueType>>;
} // end namespace AMDiS
#pragma once
#include <string>
#include <memory>
#include <dune/istl/bvector.hh>
#include <dune/functions/functionspacebases/interpolate.hh>
#include <amdis/Output.hpp>
#include <amdis/common/ClonablePtr.hpp>
#include <amdis/linear_algebra/DOFVectorBase.hpp>
namespace AMDiS
{
template <class FeSpaceType, class ValueType = Dune::FieldVector<double,1>>
class DOFVector
{
using Self = DOFVector;
public:
using FeSpace = FeSpaceType;
using BaseVector = Dune::BlockVector<ValueType>;
using size_type = typename FeSpace::size_type;
using field_type = typename ValueType::field_type;
using value_type = ValueType;
/// Constructor. Constructs new BaseVector.
DOFVector(FeSpace const& feSpace, std::string name)
: feSpace(feSpace)
, name(name)
, vector(ClonablePtr<BaseVector>::make())
{
compress();
}
/// Constructor. Takes pointer of data-vector.
DOFVector(FeSpace const& feSpace, std::string name,
BaseVector& vector_ref)
: feSpace(feSpace)
, name(name)
, vector(vector_ref)
{}
/// Return the basis \ref feSpace of the vector
FeSpace const& getFeSpace() const
{
return feSpace;
}
/// Return the data-vector \ref vector
BaseVector const& getVector() const
template <class T, class = void>
struct BlockVectorType
{
using type = Dune::FieldVector<T,1>;
};
template <class T>
struct BlockVectorType<T, typename T::field_type>
{
using type = T;
};
template <class ValueType>
class IstlVector
{
return *vector;
}
public:
/// The type of the elements of the DOFVector
using value_type = typename BlockVectorType<ValueType>::type;
/// Return the data-vector \ref vector
BaseVector& getVector()
{
return *vector;
}
/// The vector type of the underlying base vector
using BaseVector = Dune::BlockVector<value_type>;
/// Return the size of the \ref feSpace
size_type getSize() const
{
return feSpace.size();
}
/// The index/size - type
using size_type = typename BaseVector::size_type;
/// Return the \ref name of this vector
std::string getName() const
{
return name;
}
public:
/// Constructor. Constructs new BaseVector.
IstlVector() = default;
/// Resize the \ref vector to the size of the \ref feSpace.
void compress()
{
vector->resize(getSize() / value_type::dimension);
}
/// Return the data-vector \ref vector
BaseVector const& vector() const
{
return vector_;
}
/// Return the data-vector \ref vector
BaseVector& vector()
{
return vector_;
}
/// Access the entry \p i of the \ref vector with read-access.
value_type const& operator[](size_type i) const
{
test_exit_dbg(i < vector->size() ,
"Index ", i, " out of range [0,", vector->size(), ")" );
return (*vector)[i];
}
/// Access the entry \p i of the \ref vector with write-access.
value_type& operator[](size_type i)
{
test_exit_dbg(i < vector->size() ,
"Index ", i, " out of range [0,", vector->size(), ")" );
return (*vector)[i];
}
/// interpolate a function \p f to the basis \ref feSpace and store the
/// coefficients in \ref vector.
template <class F>
void interpol(F const& f)
{
Dune::Functions::interpolate(feSpace, *vector, f);
}
/// Return the current size of the \ref vector_
size_type size() const
{
return vector_.size();
}
/// Calls the copy assignment operator of the BaseVector \ref vector
void copy(Self const& that)
{
*vector = that.getVector();
}
/// Resize the \ref vector_ to the size \p s
void resize(size_type s)
{
vector_.resize(s);
}
private:
FeSpace const& feSpace;
std::string name;
ClonablePtr<BaseVector> vector;
/// Access the entry \p i of the \ref vector with read-access.
value_type const& operator[](size_type i) const
{
test_exit_dbg(i < vector_.size(),
"Index ", i, " out of range [0,", vector_.size(), ")" );
return vector_[i];
}
// friend class declarations
template <class, class>
friend class SystemVector;
};
/// Access the entry \p i of the \ref vector with write-access.
value_type& operator[](size_type i)
{
test_exit_dbg(i < vector_.size(),
"Index ", i, " out of range [0,", vector_.size(), ")" );
return vector_[i];
}
private:
BaseVector vector_;
};
template <class BasisType, class VectorType = double>
using DOFVector = DOFVectorBase<BasisType, IstlVector<VectorType>>;
/// Constructor a dofvector from given basis and name
template <class ValueType = double, class Basis>
DOFVector<Basis, ValueType>
makeDOFVector(Basis const& basis)
{
return {basis};
}
} // end namespace AMDiS
#pragma once
#include <algorithm>
#include <string>
#include <amdis/Output.hpp>
#include <amdis/linear_algebra/RunnerInterface.hpp>
#include <amdis/linear_algebra/SolverInfo.hpp>
namespace AMDiS
{
/**
* \ingroup Solver
* \class AMDiS::DirectRunner
* \brief \implements RunnerInterface for the (external) direct solvers
*/
template <class Solver, class Matrix, class VectorX, class VectorB>
class DirectRunner
: public RunnerInterface<Matrix, VectorX, VectorB>
{
protected:
using Super = RunnerInterface<Matrix, VectorX, VectorB>;
using BaseSolver = Dune::InverseOperator<VectorX, VectorB>;
public:
/// Constructor.
DirectRunner(std::string prefix)
: solverCreator_(prefix)
{}
/// Implementes \ref RunnerInterface::init()
virtual void init(Matrix const& A) override
{
solver_ = solverCreator_.create(A);
}
/// Implementes \ref RunnerInterface::exit()
virtual void exit() override
{
solver_.reset();
}
/// Implementes \ref RunnerInterface::solve()
virtual int solve(Matrix const& A, VectorX& x, VectorB const& b,
SolverInfo& solverInfo) override
{
// storing some statistics
Dune::InverseOperatorResult statistics;
// solve the linear system
VectorB _b = b;
solver_->apply(x, _b, statistics);
solverInfo.setRelResidual(statistics.reduction);
return 0;
}
private:
ISTLSolverCreator<Solver> solverCreator_;
std::shared_ptr<BaseSolver> solver_;
};
}
#pragma once
namespace AMDiS
{
template <class ISTLSolver, bool specialized = true>
struct ISTLSolverCreator;
} // end namespace AMDiS
#pragma once
#include <amdis/linear_algebra/istl/ISTL_Solver.hpp>
#include <amdis/linear_algebra/istl/Preconditioner.hpp>
#include <dune/istl/preconditioner.hh>
#include <amdis/linear_algebra/RunnerInterface.hpp>
#include <amdis/linear_algebra/SolverInfo.hpp>
#include <amdis/linear_algebra/istl/Fwd.hpp>
#include <amdis/linear_algebra/istl/ISTL_Preconditioner.hpp>
namespace AMDiS
{
template <class Matrix, class VectorX, class VectorB>
template <class ISTLSolver, class Matrix, class VectorX, class VectorB>
class ISTLRunner
: public RunnerInterface<Matrix, VectorX, VectorB>
: public RunnerInterface<Matrix, VectorX, VectorB>
{
using LinOperator = Dune::MatrixAdapter<Matrix, VectorX, VectorB>;
using BaseSolver = Dune::InverseOperator<VectorX, VectorB>;
using PreconRunner = ISTLPreconditioner<Matrix, VectorX, VectorB>;
using PreconBase = PreconditionerInterface<Matrix, VectorX, VectorB>;
using BasePrecon = Dune::Preconditioner<VectorX, VectorB>;
using ISTLPrecon = ISTLPreconInterface<Matrix, VectorX, VectorB>;
public:
ISTLRunner(std::string solverName, std::string prefix)
: solverName(solverName)
, prefix(prefix)
, solverCreator(prefix)
ISTLRunner(std::string prefix)
: solverCreator_(prefix)
{
// get creator string for preconditioner
std::string preconName = "no";
Parameters::get(prefix + "->left precon", preconName);
if (preconName.empty() || preconName == "no")
Parameters::get(prefix + "->right precon", preconName);
if (preconName.empty() || preconName == "no")
Parameters::get(prefix + "->precon->name", preconName);
precon = std::make_shared<PreconRunner>(preconName, prefix + "->precon");
initPrecon(prefix);
}
/// Implementes \ref RunnerInterface::init()
virtual void init(Matrix const& A) override
{
precon->init(A);
Matrix& _A = const_cast<Matrix&>(A); // Unschoen!!!