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

Added flat matrix and vector used for ElementMatrix and ElementVector

parent 9f35f6d0
No related branches found
No related tags found
No related merge requests found
......@@ -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