Skip to content
Snippets Groups Projects
Commit 54ee6051 authored by Oliver Sander's avatar Oliver Sander
Browse files

[!241] MultiTypeBlockVector: Inherit tuple constructors

Merge branch 'feature/mtbv-inherit-tuple-constructors' into 'master'

ref:core/dune-istl

-   Makes member function count const
-   Inherits tuple constructors so that MultiTypeBlockVector can be
    constructed from existing Vectors, or we can even construct it with
    references to existing vectors.
-   Test construction from references in the test
-   Fixes the static_assert in the test that shouldn't really have compiled
    before

See merge request [!241]

  [!241]: gitlab.dune-project.org/core/dune-istl/merge_requests/241
parents 7cb26196 ce4a4d94
No related branches found
No related tags found
1 merge request!241MultiTypeBlockVector: Inherit tuple constructors
Pipeline #14527 passed
......@@ -11,6 +11,12 @@
- Support for SuiteSparse's CHOLMOD providing a sparse Cholesky
factorization.
- `MultiTypeBlockVector<Args...>` now inherits the constructors from its
parent type (`std::tuple<Args...>`). This means you can now also construct
`MultiTypeBlockVector`s from values or references of BlockVectors.
- `MultiTypeBlockVector::count()` is now `const`
# Release 2.6
- `BDMatrix` objects can now be constructed and assigned from `std::initializer_list`.
......
......@@ -55,9 +55,14 @@ namespace Dune {
: public std::tuple<Args...>
{
/** \brief Helper type */
typedef std::tuple<Args...> tupleType;
typedef std::tuple<Args...> TupleType;
public:
/**
* \brief Get the constructors from tuple
*/
using TupleType::TupleType;
/**
* own class' type
*/
......@@ -81,7 +86,7 @@ namespace Dune {
/**
* number of elements
*/
int count()
int count() const
{
return sizeof...(Args);
}
......@@ -105,7 +110,7 @@ namespace Dune {
* \endcode
*/
template< std::size_t index >
typename std::tuple_element<index,tupleType>::type&
typename std::tuple_element<index,TupleType>::type&
operator[] ( const std::integral_constant< std::size_t, index > indexVariable )
{
DUNE_UNUSED_PARAMETER(indexVariable);
......@@ -118,7 +123,7 @@ namespace Dune {
* explanation of how to use it.
*/
template< std::size_t index >
const typename std::tuple_element<index,tupleType>::type&
const typename std::tuple_element<index,TupleType>::type&
operator[] ( const std::integral_constant< std::size_t, index > indexVariable ) const
{
DUNE_UNUSED_PARAMETER(indexVariable);
......
......@@ -14,74 +14,92 @@
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/indices.hh>
#include <dune/common/float_cmp.hh>
#include <dune/istl/bvector.hh>
#include <dune/istl/multitypeblockvector.hh>
using namespace Dune;
int main(int argc, char** argv) try
template<typename... Args>
void testMultiVector(const MultiTypeBlockVector<Args...>& multiVector)
{
using namespace Indices;
// test operator<<
std::cout << multiVector << std::endl;
MultiTypeBlockVector<BlockVector<FieldVector<double,3> >, BlockVector<FieldVector<double,1> > > multiVector;
// test method 'count'
std::cout << "multi vector has " << multiVector.count() << " first level blocks" << std::endl;
multiVector[_0] = {{1,0,0},
{0,1,0},
{0,0,1}};
static_assert(MultiTypeBlockVector<Args...>::size()==2, "Method MultiTypeBlockVector::size() returned wrong value!");
multiVector[_1] = {3.14, 42};
if (multiVector.count() != 2)
DUNE_THROW(Exception, "Method MultiTypeBlockVector::count returned wrong value!");
// Test copy construction
auto multiVector2 = multiVector;
// test operator<<
std::cout << multiVector << std::endl;
// Test assignment operator
multiVector2 = multiVector;
// test method 'count'
std::cout << "multi vector has " << multiVector.count() << " first level blocks" << std::endl;
// Test operator+=
multiVector2 += multiVector;
static_assert(multiVector.size()==2, "Method MultiTypeBlockVector::size() returned wrong value!");
// Test operator-=
multiVector2 -= multiVector;
if (multiVector.count() != 2)
DUNE_THROW(Exception, "Method MultiTypeBlockVector::count returned wrong value!");
// Test multiplication with scalar
multiVector2 *= (double)0.5;
multiVector2 *= (int)2;
multiVector2 *= (float)0.5;
// Test copy construction
auto multiVector2 = multiVector;
// Test assignment from scalar
multiVector2 = (double)0.5;
multiVector2 = (int)2;
multiVector2 = (float)0.5;
// Test assignment operator
multiVector2 = multiVector;
// Test axpy
multiVector2.axpy(-1, multiVector);
// Test operator+=
multiVector2 += multiVector;
// Test two_norm
std::cout << "multivector2 has two_norm: " << multiVector2.two_norm() << std::endl;
// Test operator-=
multiVector2 -= multiVector;
// Test two_norm2
std::cout << "multivector2 has two_norm2: " << multiVector2.two_norm2() << std::endl;
// Test multiplication with scalar
multiVector2 *= (double)0.5;
multiVector2 *= (int)2;
multiVector2 *= (float)0.5;
// Test infinity_norm
std::cout << "multivector2 has infinity_norm: " << multiVector2.infinity_norm() << std::endl;
// Test assignment from scalar
multiVector2 = (double)0.5;
multiVector2 = (int)2;
multiVector2 = (float)0.5;
// Test operator*
std::cout << multiVector * multiVector2 << std::endl;
// Test axpy
multiVector2.axpy(-1, multiVector);
// Test method 'dot'
std::cout << multiVector.dot(multiVector2) << std::endl;
}
int main(int argc, char** argv) try
{
using namespace Indices;
MultiTypeBlockVector<BlockVector<FieldVector<double,3> >, BlockVector<FieldVector<double,1> > > multiVector;
multiVector[_0] = {{1,0,0},
{0,1,0},
{0,0,1}};
multiVector[_1] = {3.14, 42};
// Test two_norm
std::cout << "multivector2 has two_norm: " << multiVector2.two_norm() << std::endl;
testMultiVector(multiVector);
// Test two_norm2
std::cout << "multivector2 has two_norm2: " << multiVector2.two_norm2() << std::endl;
// create a "shallow" copy
MultiTypeBlockVector<BlockVector<FieldVector<double,3> >&, BlockVector<FieldVector<double,1> >& >
multiVectorRef(multiVector[_0], multiVector[_1]);
// Test infinity_norm
std::cout << "multivector2 has infinity_norm: " << multiVector2.infinity_norm() << std::endl;
multiVectorRef[_0][0][0] = 5.0;
// Test operator*
std::cout << multiVector * multiVector2 << std::endl;
if (!FloatCmp::eq(multiVectorRef[_0][0][0], multiVector[_0][0][0]))
DUNE_THROW(Exception, "Modifying an entry of the referencing vector failed!");
// Test method 'dot'
std::cout << multiVector.dot(multiVector2) << std::endl;
testMultiVector(multiVectorRef);
return 0;
}
......
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