...
 
Commits (2)
  • Oliver Sander's avatar
    [!241] MultiTypeBlockVector: Inherit tuple constructors · 448c0881
    Oliver Sander authored
    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
    
    (cherry picked from commit 54ee6051)
    448c0881
  • Martin Nolte's avatar
    [!242] [!241] MultiTypeBlockVector: Inherit tuple constructors · bb0fee97
    Martin Nolte authored
    Merge branch 'backport/feature/mtbv-inherit-tuple-constructors' into 'releases/2.6'
    
    ref:core/dune-istl 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]]
    
    (cherry picked from commit 54ee6051)
    
    See merge request [!242]
    
      [!241]: gitlab.dune-project.org/core/dune-istl/merge_requests/241
      [!242]: gitlab.dune-project.org/core/dune-istl/merge_requests/242
    bb0fee97
......@@ -8,3 +8,9 @@
- The solver infrastructure was updated to support SIMD data types (see
current changes in `dune-common`). This allows to solve multiple systems
simultaniously using vectorization.
- `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`
......@@ -54,9 +54,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
*/
......@@ -80,7 +85,7 @@ namespace Dune {
/**
* number of elements
*/
int count()
int count() const
{
return sizeof...(Args);
}
......@@ -104,7 +109,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);
......@@ -117,7 +122,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;
}
......