Skip to content
Snippets Groups Projects
Commit b374ce9e authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'feature/flat_mat_vec' into 'master'

Added flat matrix and vector used for ElementMatrix and ElementVector

See merge request !94
parents 9f35f6d0 97813675
No related branches found
No related tags found
1 merge request!94Added flat matrix and vector used for ElementMatrix and ElementVector
......@@ -15,6 +15,8 @@ install(FILES
FieldMatVec.hpp
FieldMatVec.inc.hpp
Filesystem.hpp
FlatMatrix.hpp
FlatVector.hpp
ForEach.hpp
HybridSize.hpp
Index.hpp
......
#pragma once
#include <type_traits>
#include <vector>
namespace AMDiS
{
/// Dense matrix with row-wise storage in flat data vector
template <class T, class Allocator = std::allocator<T>>
class FlatMatrix
: public std::vector<T,Allocator>
{
using Super = std::vector<T,Allocator>;
public:
using value_type = T;
using size_type = typename Super::size_type;
using reference = typename Super::reference;
using const_reference = typename Super::const_reference;
private:
/// Accessor to a row of the matrix.
template <class Vector>
struct AccessProxy
{
/// Access the column entry `col` of the row `row_` of this accessor.
/// @{
template <class V = Vector, std::enable_if_t<not std::is_const<V>::value,int> = 0>
reference operator[](size_type col)
{
return (*vector_)[row_*cols_ + col];
}
const_reference operator[](size_type col) const
{
return (*vector_)[row_*cols_ + col];
}
// @}
Vector* vector_;
size_type row_;
size_type cols_;
};
public:
/// Default constructor, creates an empty 0x0 matrix.
FlatMatrix() = default;
/// Construct a new matrix with rows `r` and columns `c` and all values
/// initialized by copies of value `v`.
FlatMatrix(size_type r, size_type c, value_type v = {})
: Super(r*c, v)
, rows_(r)
, cols_(c)
{}
/// Assign value `s` to all entries of the matrix
FlatMatrix& operator=(value_type s)
{
Super::assign(Super::size(), s);
return *this;
}
/// Resizes the container to contain r x c elements.
/**
* If the current `rows*cols` is greater than `r*c`, the container is reduced
* to its first `r*c` elements. If the current `rows*cols` is less than `r*c`,
* additional copies of value `v` are appended.
**/
void resize(size_type r, size_type c, value_type v = {})
{
Super::resize(r*c, v);
rows_ = r;
cols_ = c;
}
/// Return the number of rows of the matrix
size_type rows() const noexcept
{
return rows_;
}
/// Return the number of columns of the matrix
size_type cols() const noexcept
{
return cols_;
}
/// Return the number of entries in the matrix, i.e. `rows*cols`.
using Super::size;
/// Return accessor to the `row` of the matrix, see \ref AccessProxy
/// @{
AccessProxy<Super> operator[](size_type row)
{
return AccessProxy<Super>{static_cast<Super*>(this), row, cols_};
}
AccessProxy<Super const> operator[](size_type row) const
{
return AccessProxy<Super const>{static_cast<Super const*>(this), row, cols_};
}
/// @}
private:
size_type rows_ = 0;
size_type cols_ = 0;
};
} // end namespace AMDiS
#pragma once
#include <vector>
namespace AMDiS
{
/// Flat data vector to be used in assembling as element vector
template <class T, class Allocator = std::allocator<T>>
class FlatVector
: public std::vector<T,Allocator>
{
public:
using std::vector<T,Allocator>::vector;
/// Assign value `s` to all entries of the vector
FlatVector& operator=(T s)
{
this->assign(this->size(), s);
return *this;
}
};
} // end namespace AMDiS
......@@ -5,6 +5,7 @@
#include <dune/common/timer.hh>
#include <amdis/OperatorList.hpp>
#include <amdis/common/FlatMatrix.hpp>
#include <amdis/common/Math.hpp>
#include <amdis/typetree/MultiIndex.hpp>
#include <amdis/typetree/TreePath.hpp>
......@@ -43,7 +44,7 @@ namespace AMDiS
using BaseMatrix = typename Backend::BaseMatrix;
/// The type of the matrix filled on an element with local contributions
using ElementMatrix = Dune::DynamicMatrix<value_type>;
using ElementMatrix = FlatMatrix<value_type>;
public:
/// Constructor. Stores the shared_ptr to the bases.
......
......@@ -9,6 +9,7 @@
#include <amdis/DataTransfer.hpp>
#include <amdis/GridTransferManager.hpp>
#include <amdis/OperatorList.hpp>
#include <amdis/common/FlatVector.hpp>
#include <amdis/common/Math.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/linearalgebra/DOFVectorInterface.hpp>
......@@ -73,7 +74,7 @@ namespace AMDiS
using BaseVector = typename Backend::BaseVector;
/// The type of the vector filled on an element with local contributions
using ElementVector = Dune::DynamicVector<value_type>;
using ElementVector = FlatVector<value_type>;
/// Defines an interface to transfer the data during grid adaption
using DataTransfer = DataTransferInterface<Self>;
......
......@@ -45,6 +45,9 @@ dune_add_test(SOURCES FiniteElementTypeTest.cpp
dune_add_test(SOURCES FilesystemTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES FlatMatVecTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES GlobalIdSetTest.cpp
LINK_LIBRARIES amdis
MPI_RANKS 2
......
#include <cmath>
#include <amdis/common/FlatMatrix.hpp>
#include <amdis/common/FlatVector.hpp>
#include "Tests.hpp"
using namespace AMDiS;
// -----------------------------------------------------------------------------
void test0()
{
using V = FlatVector<double>;
// create an empty vector
V a;
// size of the vector
AMDIS_TEST_EQ(a.size(), 0);
// Resize the vector
a.resize(3, 0.0);
AMDIS_TEST_EQ(a.size(), 3);
AMDIS_TEST_EQ(a[0], 0.0);
AMDIS_TEST_EQ(a[1], 0.0);
AMDIS_TEST_EQ(a[2], 0.0);
// access component
a[0] = 0.0;
a[1] = 0.5;
a[2] = 1.0;
// assign value to all entries
a = 2.0;
AMDIS_TEST_EQ(a[0], 2.0);
AMDIS_TEST_EQ(a[1], 2.0);
AMDIS_TEST_EQ(a[2], 2.0);
}
// -----------------------------------------------------------------------------
void test1()
{
using M = FlatMatrix<double>;
// create an empty matrix
M m;
AMDIS_TEST_EQ(m.size(), 0);
AMDIS_TEST_EQ(m.rows(), 0);
AMDIS_TEST_EQ(m.cols(), 0);
// resize the matrix
m.resize(2,3, 0.0);
AMDIS_TEST_EQ(m.size(), 2*3);
AMDIS_TEST_EQ(m.rows(), 2);
AMDIS_TEST_EQ(m.cols(), 3);
typename M::difference_type s = std::distance(m.begin(),m.end());
AMDIS_TEST_EQ(s, 2*3);
// test element access
AMDIS_TEST_EQ(m[0][0], 0.0);
AMDIS_TEST_EQ(m[1][2], 0.0);
// test assignment of value
m = 1.0;
AMDIS_TEST_EQ(m[0][0], 1.0);
AMDIS_TEST_EQ(m[1][2], 1.0);
for (std::size_t i = 0; i < m.rows(); ++i)
for (std::size_t j = 0; j < m.cols(); ++j)
m[i][j] = 2.0;
// access matrix entries
for (std::size_t i = 0; i < m.rows(); ++i)
for (std::size_t j = 0; j < m.cols(); ++j)
AMDIS_TEST_EQ(m[i][j], 2.0);
// test iterators
for (auto& mij : m)
mij = 3.0;
for (auto const& mij : m)
AMDIS_TEST_EQ(mij, 3.0);
// test data array
m = 4.0;
double const* data = m.data();
for (std::size_t i = 0; i < m.size(); ++i)
AMDIS_TEST_EQ(data[i], 4.0);
}
int main()
{
test0();
test1();
return report_errors();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment