Commit 8521711f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

added DOFVector test

parent 4a878787
#pragma once
#include <cstddef>
namespace AMDiS
{
template <class T>
struct Triplet
{
std::size_t row, cols;
T value;
};
} // end namespace AMDiS
#pragma once
#include <cstddef>
namespace AMDiS
{
template <class T>
struct Triplet
template <class RowBasisType, class ColBasisType>
class DOFMatrixBase
{
std::size_t row, cols;
T value;
public:
/// The type of the finite element space / basis of the row
using RowBasis = RowBasisType;
/// The type of the finite element space / basis of the column
using ColBasis = ColBasisType;
/// The index/size - type
using size_type = typename RowBasis::size_type;
public:
/// Constructor. Constructs new BaseVector.
DOFMatrixBase(RowBasis const& rowBasis, ColBasis const& colBasis)
: rowBasis_(&rowBasis)
, colBasis_(&colBasis)
{}
/// Return the row-basis \ref rowBasis of the matrix
RowBasis const& rowBasis() const
{
return *rowBasis_;
}
/// Return the col-basis \ref colBasis of the matrix
ColBasis const& colBasis() const
{
return *colBasis_;
}
/// Return the size of the \ref rowBasis_
size_type rows() const
{
return rowBasis_->dimension();
}
/// Return the size of the \ref colBasis_
size_type cols() const
{
return colBasis_->dimension();
}
protected:
RowBasis const* rowBasis_;
ColBasis const* colBasis_;
};
} // end namespace AMDiS
......@@ -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
#pragma once
#include <list>
#include <string>
#include <memory>
......@@ -8,6 +9,7 @@
#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>
......@@ -28,50 +30,30 @@ namespace AMDiS
template <class RowBasisType, class ColBasisType,
class ValueType = double>
class DOFMatrix
: public DOFMatrixBase<RowBasisType, ColBasisType>
{
public:
/// The type of the finite element space / basis of the row
using RowBasis = RowBasisType;
/// The type of the finite element space / basis of the column
using ColBasis = ColBasisType;
using Super = DOFMatrixBase<RowBasisType, ColBasisType>;
public:
/// The type of the elements of the DOFMatrix
using value_type = typename BlockMatrixType<ValueType>::type;
/// 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.
DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis)
: rowBasis_(&rowBasis)
, colBasis_(&colBasis)
DOFMatrix(RowBasisType const& rowBasis, ColBasisType const& colBasis)
: Super(rowBasis, colBasis)
, matrix_(ClonablePtr<BaseMatrix>::make())
{}
/// Constructor. Takes reference to a base matrix.
DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis, BaseMatrix& matrix)
: rowBasis_(&rowBasis)
, colBasis_(&colBasis)
DOFMatrix(RowBasisType const& rowBasis, ColBasisType const& colBasis, BaseMatrix& matrix)
: Super(rowBasis, colBasis)
, matrix_(matrix)
{}
/// Return the row-basis \ref rowBasis of the matrix
RowBasis const& rowBasis() const
{
return *rowBasis_;
}
/// Return the col-basis \ref colBasis of the matrix
ColBasis const& colBasis() const
{
return *colBasis_;
}
/// Return the data-vector \ref vector
BaseMatrix const& matrix() const
{
......@@ -84,50 +66,28 @@ namespace AMDiS
return *matrix_;
}
/// Return the size of the \ref feSpace
size_type rows() const
{
return rowBasis_->size();
}
size_type cols() const
{
return colBasis_->size();
}
/// Access the entry \p i of the \ref vector with read-access.
template <class Index>
value_type const& operator()(Index row, Index col) const
{
size_type r = flatMultiIndex(row), c = flatMultiIndex(col);
test_exit_dbg( initialized_, "Occupation pattern not initialized!");
test_exit_dbg( r < rows() && c < cols() ,
"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.
template <class Index>
value_type& operator()(Index row, Index col)
{
size_type r = flatMultiIndex(row), c = flatMultiIndex(col);
auto r = flatMultiIndex(row), c = flatMultiIndex(col);
test_exit_dbg( initialized_, "Occupation pattern not initialized!");
test_exit_dbg( r < rows() && c < cols() ,
"Indices out of range [0,", rows(), ")x[0,", cols(), ")" );
test_exit_dbg( r < this->rows() && c < this->cols() ,
"Indices out of range [0,", this->rows(), ")x[0,", this->cols(), ")" );
return (*matrix_)[r][c];
}
/// create occupation pattern and apply it to the matrix
void init(bool prepareForInsertion)
{
occupationPattern_.resize(rowBasis_->size(), colBasis_->size());
occupationPattern_.resize(this->rows(), this->cols());
// A loop over all elements of the grid
auto rowLocalView = rowBasis_->localView();
auto colLocalView = colBasis_->localView();
auto rowLocalView = this->rowBasis_->localView();
auto colLocalView = this->colBasis_->localView();
for (const auto& element : elements(rowBasis_->gridView())) {
for (const auto& element : elements(this->rowBasis_->gridView())) {
rowLocalView.bind(element);
colLocalView.bind(element);
......@@ -169,14 +129,10 @@ namespace AMDiS
}
}
std::list<Triplet<value_type>> columns; // symmetric dbc not yet implemented
return columns;
return std::list<Triplet<value_type>>{};
}
private:
RowBasis const* rowBasis_;
ColBasis const* colBasis_;
ClonablePtr<BaseMatrix> matrix_;
Dune::MatrixIndexSet occupationPattern_;
......
......@@ -123,4 +123,28 @@ namespace AMDiS
ClonablePtr<BaseVector> vector_;
};
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
// Deduction rule
template <class Basis, class T>
DOFVector(Basis const& basis, Dune::BlockVector<T>& coefficients)
-> DOFVector<Basis, typename T::field_type>;
#endif
/// Constructor a dofvector from given basis and name
template <class ValueType = double, class Basis>
DOFVector<Basis, ValueType>
makeDOFVector(Basis const& basis)
{
return {basis};
}
/// Constructor a dofvector from given basis, name, and coefficient vector
template <class Basis, class T>
DOFVector<Basis, typename T::field_type>
makeDOFVector(Basis const& basis, Dune::BlockVector<T>& coefficients)
{
return {basis, coefficients};
}
} // end namespace AMDiS
......@@ -12,6 +12,7 @@
#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>
......@@ -22,20 +23,14 @@ namespace AMDiS
template <class RowBasisType, class ColBasisType,
class ValueType = double>
class DOFMatrix
: public DOFMatrixBase<RowBasisType, ColBasisType>
{
public:
/// The type of the finite element space / basis of the row
using RowBasis = RowBasisType;
/// The type of the finite element space / basis of the column
using ColBasis = ColBasisType;
using Super = DOFMatrixBase<RowBasisType, ColBasisType>;
public:
/// The matrix type of the underlying base matrix
using BaseMatrix = mtl::compressed2D<ValueType>;
/// The index/size - type
using size_type = typename BaseMatrix::size_type;
/// The type of the elements of the DOFMatrix
using value_type = ValueType;
......@@ -44,31 +39,17 @@ namespace AMDiS
public:
/// Constructor. Constructs new BaseMatrix.
DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis)
: rowBasis_(&rowBasis)
, colBasis_(&colBasis)
DOFMatrix(RowBasisType const& rowBasis, ColBasisType const& colBasis)
: Super(rowBasis, colBasis)
, matrix_(ClonablePtr<BaseMatrix>::make())
{}
/// Constructor. Takes a reference to a base matrix
DOFMatrix(RowBasis const& rowBasis, ColBasis const& colBasis, BaseMatrix& matrix)
: rowBasis_(&rowBasis)
, colBasis_(&colBasis)
DOFMatrix(RowBasisType const& rowBasis, ColBasisType const& colBasis, BaseMatrix& matrix)
: Super(rowBasis, colBasis)
, matrix_(matrix)
{}
/// Return the row-basis \ref rowBasis_ of the matrix
RowBasis const& rowBasis() const
{
return *rowBasis_;
}
/// Return the col-basis \ref colBasis_ of the matrix
ColBasis const& colBasis() const
{
return *colBasis_;
}
/// Return a reference to the data-matrix \ref matrix
BaseMatrix& matrix()
{
......@@ -83,18 +64,6 @@ namespace AMDiS
return *matrix_;
}
/// Return the size of the row \ref feSpace
size_type rows() const
{
return rowBasis_->size();
}
/// Return the size of the column \ref feSpace
size_type cols() const
{
return colBasis_->size();
}
/// \brief Returns an update-proxy of the inserter, to inserte/update a value at
/// position (\p r, \p c) in the matrix. Need an insertionMode inserter, that can
......@@ -102,10 +71,10 @@ namespace AMDiS
template <class Index>
auto operator()(Index row, Index col)
{
size_type r = flatMultiIndex(row), c = flatMultiIndex(col);
auto r = flatMultiIndex(row), c = flatMultiIndex(col);
test_exit_dbg(inserter_, "Inserter not initilized!");
test_exit_dbg(r < rows() && c < cols(),
"Indices out of range [0,", rows(), ")x[0,", cols(), ")" );
test_exit_dbg(r < this->rows() && c < this->cols(),
"Indices out of range [0,", this->rows(), ")x[0,", this->cols(), ")" );
return (*inserter_)[r][c];
}
......@@ -116,8 +85,8 @@ namespace AMDiS
test_exit(!inserter_, "Matrix already in insertion mode!");
calculateSlotSize();
matrix_->change_dim(rowBasis_->dimension(), colBasis_->dimension());
test_exit(num_rows(*matrix_) == rowBasis_->dimension() && num_cols(*matrix_) == colBasis_->dimension(),
matrix_->change_dim(this->rows(), this->cols());
test_exit(num_rows(*matrix_) == this->rows() && num_cols(*matrix_) == this->cols(),
"Wrong dimensions in matrix");
if (prepareForInsertion) {
set_to_zero(*matrix_);
......@@ -143,30 +112,13 @@ namespace AMDiS
/// a one on the diagonal of the matrix.
auto applyDirichletBC(std::vector<char> const& dirichletNodes)
{
std::list<Triplet<value_type>> columns;
// Define the property maps
auto row = mtl::mat::row_map(*matrix_);
auto col = mtl::mat::col_map(*matrix_);
auto value = mtl::mat::value_map(*matrix_);
// iterate over the matrix
#if 0
for (auto r : mtl::major_of(*matrix)) { // rows or columns
for (auto i : mtl::nz_of(r)) { // non-zeros within
if (dirichletNodes[row(i)]) {
// set identity row
value(i, (row(i) == col(i) ? value_type(1) : value_type(0)) );
}
else if (dirichletNodes[col(i)]) {
columns.push_back({row(i), col(i), value(i)});
value(i, value_type(0));
}
}
}
#endif
for (auto r : mtl::rows_of(*matrix_)) { // rows or columns
for (auto r : mtl::rows_of(*matrix_)) { // rows of the matrix
if (dirichletNodes[r.value()]) {
for (auto i : mtl::nz_of(r)) { // non-zeros within
// set identity row
......@@ -175,67 +127,8 @@ namespace AMDiS
}
}
return columns;
}
#if 0
void applyPeriodicBC(std::vector<char> const& periodicNodes,
std::map<size_t, size_t> const& association, bool applyRow, bool applyCol)
{
bool apply = applyRow && applyCol;
// Define the property maps
auto row = mtl::mat::row_map(*matrix);
auto col = mtl::mat::col_map(*matrix);
auto value = mtl::mat::value_map(*matrix);
std::vector<std::map<size_t, std::list<value_type>>> row_values(num_cols(*matrix));
std::vector<std::map<size_t, std::list<value_type>>> col_values(num_rows(*matrix));
std::vector<char> dualNodes(periodicNodes.size(), 0);
// iterate over the matrix to collect the values and erase the source-row/col
for (auto r : mtl::major_of(*matrix)) { // rows or columns
for (auto i : mtl::nz_of(r)) { // non-zeros within
if (applyRow && periodicNodes[row(i)]) {
row_values[col(i)][association[row(i)]].push_back(value(i));
value(i, value_type(0));
dualNodes[association[row(i)]] = 1;
} else if (applyCol && periodicNodes[col(i)]) {
col_values[row(i)][association[col(i)]].push_back(value(i));
value(i, value_type(0));
}
}
}
// TODO: use inserter for assignment of values!!!
// iterate over the matrix to assign the values
for (auto r : mtl::major_of(*matrix)) { // rows or columns
for (auto i : mtl::nz_of(r)) { // non-zeros within
if (applyRow && dualNodes[row(i)]) {
value(i, std::accumulate(row_values[col(i)][row(i)].begin(),
row_values[col(i)][row(i)].end(),
value(i)) );
}
if (applyCol && dualNodes[col(i)]) {
value(i, std::accumulate(col_values[row(i)][col(i)].begin(),
col_values[row(i)][col(i)].end(),
value(i)) );
}
}
}
// assign values 1, -1 to diagonal and associated entries
if (apply) {
Inserter ins(*matrix);
for (auto const& a : association) {
ins[a.first][a.first] << value_type( 1);
ins[a.second][a.second] << value_type( 1);
ins[a.first][a.second] << value_type(-1);
ins[a.second][a.first] << value_type(-1);
}
}
return std::list<Triplet<value_type>>{};
}
#endif
protected:
// Estimates the slot-size used in the inserter to reserve enough space per row.
......@@ -253,12 +146,6 @@ namespace AMDiS
/// The minimal number of nonzeros per row
static constexpr int MIN_NNZ_PER_ROW = 50;
/// The finite element space / basis of the row
RowBasis const* rowBasis_;
/// The finite element space / basis of the column
ColBasis const* colBasis_;
/// The data-matrix (can hold a new BaseMatrix or a pointer to external data
ClonablePtr<BaseMatrix> matrix_;
......
......@@ -123,7 +123,7 @@ namespace AMDiS
};
/// Constructor a dofvector from given basis and name
template <class Basis, class ValueType = double>
template <class ValueType = double, class Basis>
DOFVector<Basis, ValueType>
makeDOFVector(Basis const& basis)
{
......
......@@ -39,14 +39,14 @@ namespace AMDiS
Parameters::get(prefix + "->print cycle", printCycle_);
}
/// Implements \ref RunnerInterface::getLeftPrecon(), Returns \ref L_
virtual std::shared_ptr<PreconBase> getLeftPrecon() override
/// Implements \ref RunnerInterface::lLeftPrecon(), Returns \ref L_
virtual std::shared_ptr<PreconBase> leftPrecon() override
{
return L_;
}
/// Implements \ref RunnerInterface::getRightPrecon(), Returns \ref R_
virtual std::shared_ptr<PreconBase> getRightPrecon() override
/// Implements \ref RunnerInterface::rightPrecon(), Returns \ref R_
virtual std::shared_ptr<PreconBase> rightPrecon() override
{
return R_;
}
......@@ -107,14 +107,14 @@ namespace AMDiS
void initPrecon(std::string prefix)
{
// Creator for the left preconditioner
std::string leftPrecon = "", rightPrecon = "";
Parameters::get(prefix + "->left precon", leftPrecon);
Parameters::get(prefix + "->right precon", rightPrecon);
std::string leftPreconName = "", rightPreconName = "";
Parameters::get(prefix + "->left precon", leftPreconName);
Parameters::get(prefix + "->right precon", rightPreconName);
auto leftCreator
= CreatorMap<PreconBase>::getCreator(leftPrecon, prefix + "->left precon");
= CreatorMap<PreconBase>::getCreator(leftPreconName, prefix + "->left precon");
auto rightCreator
= CreatorMap<PreconBase>::getCreator(rightPrecon, prefix + "->right precon");
= CreatorMap<PreconBase>::getCreator(rightPreconName, prefix + "->right precon");
L_ = leftCreator->create();
R_ = rightCreator->create();
......
......@@ -8,6 +8,9 @@ dune_add_test(SOURCES ClonablePtrTest.cpp
dune_add_test(SOURCES ConceptsTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES DOFVectorTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES ExpressionsTest.cpp
LINK_LIBRARIES amdis
CMD_ARGS "${CMAKE_SOURCE_DIR}/examples/init/ellipt.dat.2d")
......
#include <dune/common/filledarray.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/functions/functionspacebases/compositebasis.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <amdis/LinearAlgebra.hpp>
#include "Tests.hpp"
using namespace AMDiS;
using namespace Dune::Functions::BasisFactory;
template <class B, class T>
void test_dofvector(B const& basis, DOFVector<B,T>& vec)
{
AMDIS_TEST( vec.size() == basis.dimension() );
vec.compress();
vec = T(0);
vec[0] = T(1);
auto m0 = std::min_element(std::begin(vec.vector()), std::end(vec.vector()));
auto m1 = std::max_element(std::begin(vec.vector()), std::end(vec.vector()));
AMDIS_TEST( *m0 == T(0) );
AMDIS_TEST( *m1 == T(1) );
}
int main()
{
// create grid
Dune::FieldVector<double, 2> L; L = 1.0;
auto s = Dune::filledArray<2>(1);
Dune::YaspGrid<2> grid(L, s);
// create basis
auto basis = makeBasis(grid.leafGridView(),
composite(power<2>(lagrange<2>(), flatInterleaved()), lagrange<1>(), flatLexicographic()));
using Basis = decltype(basis);
DOFVector<Basis> vec1(basis);
test_dofvector(basis, vec1);
DOFVector<Basis, float> vec2(basis);
test_dofvector(basis, vec2);
auto vec3 = makeDOFVector(basis);
test_dofvector(basis, vec3);
auto vec4 = makeDOFVector<float>(basis);
test_dofvector(basis, vec4);
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
DOFVector vec5(basis);
test_dofvector(basis, vec5);
#endif
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment