Commit 27c9ec6b authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Implemented tests for HybridSize and Access

parent 1a88fb4a
#pragma once
#include <dune/common/typeutilities.hh>
#include <amdis/common/Concepts.hpp>
#include <amdis/common/Logical.hpp>
#include <amdis/common/TypeTraits.hpp>
......@@ -13,22 +15,28 @@ namespace AMDiS
struct HasVectorAccess
{
template <class V, class I>
auto requires_(V&& v, I&& i) -> decltype( v[i] );
auto requires_(V&& v, I&& i, Dune::PriorityTag<2>) -> decltype( v[i] );
template <class V, class I>
auto requires_(V&& v, I&& i, Dune::PriorityTag<1>) -> decltype( v(i) );
};
struct HasMatrixAccess
{
template <class M, class I, class J>
auto requires_(M&& m, I&& i, J&& j) -> decltype( m[i][j] );
auto requires_(M&& m, I&& i, J&& j, Dune::PriorityTag<2>) -> decltype( m[i][j] );
template <class M, class I, class J>
auto requires_(M&& m, I&& i, J&& j, Dune::PriorityTag<1>) -> decltype( m(i,j) );
};
} // end namespace Definition
template <class V, class I>
using VectorAccessible_t = bool_t<models<Definition::HasVectorAccess(V, I)>>;
using VectorAccessible_t = bool_t<models<Definition::HasVectorAccess(V, I, Dune::PriorityTag<42>)>>;
template <class M, class I, class J>
using MatrixAccessible_t = bool_t<models<Definition::HasMatrixAccess(M, I, J)>>;
using MatrixAccessible_t = bool_t<models<Definition::HasMatrixAccess(M, I, J, Dune::PriorityTag<42>)>>;
} // end namespace Concepts
......@@ -43,31 +51,71 @@ namespace AMDiS
decltype(auto) access(Matrix&& mat, I const& i, J const& j);
#else
// access i'th component of a vector
template <class Vector, class I,
REQUIRES(Concepts::VectorAccessible_t<Vector,I>{})>
decltype(auto) access(Vector&& vec, I const& i) { return vec[i]; }
namespace Impl
{
// access i'th component of a vector using [.]
template <class Vector, class I,
class = void_t<decltype(std::declval<Vector>()[std::declval<I>()])> >
decltype(auto) access_impl(Vector&& vec, I const& i, Dune::PriorityTag<2>)
{
return vec[i];
}
// access i'th component of a vector using (.)
template <class Vector, class I,
class = void_t<decltype(std::declval<Vector>()(std::declval<I>()))> >
decltype(auto) access_impl(Vector&& vec, I const& i, Dune::PriorityTag<1>)
{
return vec(i);
}
// fall-back implementation for scalars
template <class Vector, class I>
decltype(auto) access_impl(Vector&& vec, I const& /*i*/, Dune::PriorityTag<0>)
{
return FWD(vec);
}
}
// fall-back implementation for scalars
template <class Vector, class I,
REQUIRES(not Concepts::VectorAccessible_t<Vector,I>{})>
decltype(auto) access(Vector&& vec, I const& /*i*/) { return FWD(vec); }
template <class Vector, class I>
decltype(auto) access(Vector&& vec, I const& i)
{
return Impl::access_impl(FWD(vec), i, Dune::PriorityTag<42>{});
}
// access (i,j)'th component of a matrix using [.][.]
template <class Matrix, class I, class J,
REQUIRES(Concepts::MatrixAccessible_t<Matrix,I,J>{})>
decltype(auto) access(Matrix&& mat, I const& i, J const& j) { return mat[i][j]; }
namespace Impl
{
// access (i,j)'th component of a matrix using [.][.]
template <class Matrix, class I, class J,
class = void_t<decltype(std::declval<Matrix>()[std::declval<I>(),std::declval<J>()])> >
decltype(auto) access_impl(Matrix&& mat, I const& i, J const& j, Dune::PriorityTag<2>)
{
return mat[i][j];
}
// access (i,j)'th component of a matrix using (.,.)
template <class Matrix, class I, class J,
class = void_t<decltype(std::declval<Matrix>()(std::declval<I>(),std::declval<J>()))> >
decltype(auto) access_impl(Matrix&& mat, I const& i, J const& j, Dune::PriorityTag<1>)
{
return mat(i,j);
}
// access (i,j)'th component of a matrix using (.,.)
template <class Matrix, class I, class J,
REQUIRES(not Concepts::MatrixAccessible_t<Matrix,I,J>{} && Concepts::Callable<Matrix,I,J>)>
decltype(auto) access(Matrix&& mat, I const& i, J const& j) { return mat(i,j); }
// fall-back implementation for scalars
template <class Matrix, class I, class J>
decltype(auto) access_impl(Matrix&& mat, I const& /*i*/, J const& /*j*/, Dune::PriorityTag<0>)
{
return FWD(mat);
}
}
// fall-back implementation for scalars
template <class Matrix, class I, class J,
REQUIRES(not Concepts::MatrixAccessible_t<Matrix,I,J>{} && not Concepts::Callable<Matrix,I,J>)>
decltype(auto) access(Matrix&& mat, I const& /*i*/, J const& /*j*/) { return FWD(mat); }
// access (i,j)'th component of a matrix
template <class Matrix, class I, class J>
decltype(auto) access(Matrix&& mat, I const& i, J const& j)
{
return Impl::access_impl(FWD(mat), i, j, Dune::PriorityTag<42>{});
}
#endif
......
......@@ -8,6 +8,7 @@
#include <amdis/common/Access.hpp>
#include <amdis/common/Concepts.hpp>
#include <amdis/common/Index.hpp>
#include <amdis/common/StaticSize.hpp>
namespace AMDiS
......@@ -18,9 +19,7 @@ namespace AMDiS
using DynamicVectorAccessible_t = VectorAccessible_t<V, std::size_t>;
template <class M>
using DynamicMatrixAccessible_t = bool_t<
MatrixAccessible_t<M, std::size_t, std::size_t>::value ||
Callable<M, std::size_t, std::size_t>>;
using DynamicMatrixAccessible_t = MatrixAccessible_t<M, std::size_t, std::size_t>;
} // end namespace Concept
......@@ -81,7 +80,23 @@ namespace AMDiS
REQUIRES(not Concepts::DynamicVectorAccessible_t<Vector>::value)>
constexpr Size_t<Vector> hybridSize(Vector const& vec, Dune::PriorityTag<1>) { return {}; }
} // end namespace Impl
template <class Vector>
auto hybridSize(Vector const& vec)
{
return Impl::hybridSize(vec, Dune::PriorityTag<42>{});
}
template <class Vector>
auto hybridElements(Vector const& vec)
{
return Dune::range(hybridSize(vec));
}
namespace Impl
{
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumRows(Matrix const& mat, Dune::PriorityTag<5>)
......@@ -105,7 +120,23 @@ namespace AMDiS
REQUIRES(not Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
constexpr Rows_t<Matrix> hybridNumRows(Matrix const& mat, Dune::PriorityTag<1>) { return {}; }
} // end namespace Impl
template <class Matrix>
auto hybridNumRows(Matrix const& mat)
{
return Impl::hybridNumRows(mat, Dune::PriorityTag<42>{});
}
template <class Matrix>
auto hybridRows(Matrix const& mat)
{
return Dune::range(hybridNumRows(mat));
}
namespace Impl
{
template <class Matrix,
REQUIRES(Concepts::DynamicMatrixAccessible_t<Matrix>::value)>
auto hybridNumCols(Matrix const& mat, Dune::PriorityTag<5>)
......@@ -131,33 +162,6 @@ namespace AMDiS
} // end namespace Impl
template <class Vector>
auto hybridSize(Vector const& vec)
{
return Impl::hybridSize(vec, Dune::PriorityTag<42>{});
}
template <class Vector>
auto hybridElements(Vector const& vec)
{
return Dune::range(hybridSize(vec));
}
template <class Matrix>
auto hybridNumRows(Matrix const& mat)
{
return Impl::hybridNumRows(mat, Dune::PriorityTag<42>{});
}
template <class Matrix>
auto hybridRows(Matrix const& mat)
{
return Dune::range(hybridNumRows(mat));
}
template <class Matrix>
auto hybridNumCols(Matrix const& mat)
{
......
#include <amdis/AMDiS.hpp>
#include <amdis/common/Access.hpp>
#include "Tests.hpp"
using namespace AMDiS;
struct Vec1
{
int operator[](std::size_t) const { return value; }
int& operator[](std::size_t) { return value; }
int value = 0;
};
struct Vec2
{
int operator()(std::size_t) const { return value; }
int& operator()(std::size_t) { return value; }
int value = 0;
};
struct Vec3
{
int operator[](std::size_t) const { return 0; }
int operator()(std::size_t) const { return 0; }
};
struct Mat1
{
Vec1 const& operator[](std::size_t) const { return row; }
Vec1& operator[](std::size_t) { return row; }
Vec1 row;
};
struct Mat2
{
int operator()(std::size_t,std::size_t) const { return value; }
int& operator()(std::size_t,std::size_t) { return value; }
int value = 0;
};
struct Mat3
{
Vec1 operator[](std::size_t) const { return {}; }
int operator()(std::size_t,std::size_t) const { return 0; }
};
struct NotAccessible {};
int main(int argc, char** argv)
{
AMDiS::init(argc, argv);
Vec1 vec1;
Vec2 vec2;
Vec3 vec3;
access(vec1, 1) = 2;
int i1 = access(vec1, 1);
AMDIS_TEST_EQ(i1,2);
access(vec2, 1) = 2;
int i2 = access(vec2, 1);
AMDIS_TEST_EQ(i2,2);
int i3 = access(vec3, 1);
AMDIS_TEST_EQ(i3,0);
static_assert(Concepts::VectorAccessible_t<Vec1,std::size_t>::value, "");
static_assert(Concepts::VectorAccessible_t<Vec2,std::size_t>::value, "");
static_assert(Concepts::VectorAccessible_t<Vec3,std::size_t>::value, "");
Mat1 mat1;
Mat2 mat2;
Mat3 mat3;
access(mat1, 1,1) = 2;
int j1 = access(mat1, 1,1);
AMDIS_TEST_EQ(j1,2);
access(mat2, 1,1) = 2;
int j2 = access(mat2, 1,1);
AMDIS_TEST_EQ(j2,2);
int j3 = access(mat3, 1,1);
AMDIS_TEST_EQ(j3,0);
static_assert(Concepts::MatrixAccessible_t<Mat1,std::size_t,std::size_t>::value, "");
static_assert(Concepts::MatrixAccessible_t<Mat2,std::size_t,std::size_t>::value, "");
static_assert(Concepts::MatrixAccessible_t<Mat3,std::size_t,std::size_t>::value, "");
NotAccessible notAccessible;
auto k1 = access(notAccessible,1);
auto k2 = access(notAccessible,1,1);
static_assert(std::is_same<decltype(k1),NotAccessible>::value, "");
static_assert(std::is_same<decltype(k2),NotAccessible>::value, "");
static_assert(not Concepts::VectorAccessible_t<NotAccessible,std::size_t>::value, "");
static_assert(not Concepts::MatrixAccessible_t<NotAccessible,std::size_t,std::size_t>::value, "");
AMDiS::finalize();
return 0;
}
dune_add_test(SOURCES AccessTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES AdaptInfoTest.cpp
LINK_LIBRARIES amdis)
......@@ -30,6 +33,9 @@ dune_add_test(SOURCES FiniteElementTypeTest.cpp
dune_add_test(SOURCES FilesystemTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES HybridSizeTest.cpp
LINK_LIBRARIES amdis)
dune_add_test(SOURCES IntegrateTest.cpp
LINK_LIBRARIES amdis
CMD_ARGS "${CMAKE_SOURCE_DIR}/examples/init/ellipt.dat.2d")
......
#include <amdis/AMDiS.hpp>
#include <amdis/common/HybridSize.hpp>
#include <amdis/common/TypeTraits.hpp>
#include "Tests.hpp"
using namespace AMDiS;
struct Vec1
{
static const std::size_t dimension = 1;
int operator[](std::size_t) const { return 0; }
std::size_t size() const { return 2; }
};
struct Vec2
{
static const std::size_t dimension = 1;
template <std::size_t I>
int operator[](index_t<I>) const { return 0; }
std::size_t size() const { return 2; }
};
struct Mat1
{
int operator()(std::size_t,std::size_t) const { return 0; }
std::size_t N() const { return 2; }
std::size_t M() const { return 2; }
};
struct Mat2
{
int operator()(std::size_t,std::size_t) const { return 0; }
std::size_t rows() const { return 2; }
std::size_t cols() const { return 2; }
};
struct Mat3
{
int operator()(std::size_t,std::size_t) const { return 0; }
std::size_t num_rows() const { return 2; }
std::size_t num_cols() const { return 2; }
};
struct Mat4
{
static const std::size_t rows = 1;
static const std::size_t cols = 1;
template <std::size_t I, std::size_t J>
int operator()(index_t<I>, index_t<J>) const { return 0; }
};
struct NotAccessible {};
int main(int argc, char** argv)
{
AMDiS::init(argc, argv);
Vec1 vec1;
Vec2 vec2;
AMDIS_TEST_EQ(std::size_t(hybridSize(vec1)),2);
AMDIS_TEST_EQ(std::size_t(hybridSize(vec2)),1);
auto s = hybridSize(vec2);
static_assert(VALUE(s) == 1, "");
Mat1 mat1;
Mat2 mat2;
Mat3 mat3;
Mat4 mat4;
AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat1)),2);
AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat1)),2);
AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat2)),2);
AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat2)),2);
AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat3)),2);
AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat3)),2);
AMDIS_TEST_EQ(std::size_t(hybridNumRows(mat4)),1);
AMDIS_TEST_EQ(std::size_t(hybridNumCols(mat4)),1);
auto r = hybridNumRows(mat4);
auto c = hybridNumCols(mat4);
static_assert(VALUE(r) == 1, "");
static_assert(VALUE(c) == 1, "");
AMDiS::finalize();
return 0;
}
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