From d165ee26fc6ec7f4df3af68fba3553c692eb2d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carsten=20Gr=C3=A4ser?= <graeser@mi.fu-berlin.de> Date: Tue, 20 Mar 2018 23:02:44 +0100 Subject: [PATCH] [test] Add test for istlVectorBackend() --- .../functionspacebases/test/CMakeLists.txt | 2 + .../test/istlvectorbackendtest.cc | 225 ++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 dune/functions/functionspacebases/test/istlvectorbackendtest.cc diff --git a/dune/functions/functionspacebases/test/CMakeLists.txt b/dune/functions/functionspacebases/test/CMakeLists.txt index 5da78ff..b68ef22 100644 --- a/dune/functions/functionspacebases/test/CMakeLists.txt +++ b/dune/functions/functionspacebases/test/CMakeLists.txt @@ -19,6 +19,8 @@ dune_add_test(SOURCES raviartthomasbasistest.cc) dune_add_test(SOURCES hierarchicvectorwrappertest.cc) +dune_add_test(SOURCES istlvectorbackendtest.cc) + dune_add_test(SOURCES compositebasistest.cc) install( diff --git a/dune/functions/functionspacebases/test/istlvectorbackendtest.cc b/dune/functions/functionspacebases/test/istlvectorbackendtest.cc new file mode 100644 index 0000000..fe43107 --- /dev/null +++ b/dune/functions/functionspacebases/test/istlvectorbackendtest.cc @@ -0,0 +1,225 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#include <config.h> + +#include <vector> +#include <array> + +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/reservedvector.hh> +#include <dune/common/classname.hh> +#include <dune/common/fvector.hh> +#include <dune/common/tuplevector.hh> +#include <dune/common/test/testsuite.hh> + +#include <dune/istl/bvector.hh> +#include <dune/istl/multitypeblockvector.hh> + +#include <dune/typetree/utility.hh> + +#include <dune/functions/common/type_traits.hh> +#include <dune/functions/functionspacebases/istlvectorbackend.hh> + + +using namespace Dune; + + + +/** + * \brief A Dummy global basis + * + * This is a mock class providing non-uniform size information. + * It's non-uniform in the sense, that not all multi-indices are + * do not always have the same size. + */ +template<std::size_t dim> +class GlobalBasisMoc +{ +public: + using size_type = std::size_t; + using SizePrefix = Dune::ReservedVector<std::size_t, 3>; + using MultiIndex = Dune::ReservedVector<std::size_t, 3>; + + /** + * \brief Construct from basis + */ + GlobalBasisMoc() + {} + + /** + * \brief Return number possible values for next position in multi index + * + * This shall vanish. It's just here such that this can be used + * as size provider n place of the basis. + */ + size_type size(const SizePrefix& prefix) const + { + if (prefix.size() == 0) + return 2; + if (prefix.size() == 1) + { + if (prefix[0] == 0) + return 23; + if (prefix[0] == 1) + return 42; + } + if (prefix.size() == 2) + { + if (prefix[0] == 0) + return dim; + if (prefix[0] == 1) + return 0; + } + if (prefix.size() == 3) + return 0; + assert(false); + } + + operator size_type () const + { + return 23*dim+42; + } + +}; + + +template<class Vector, class Coefficient, std::size_t dim, class MultiIndex> +Dune::TestSuite checkHierarchicVector(std::string shortName="") +{ + Dune::TestSuite test(shortName); + + using namespace Dune::TypeTree::Indices; + using Basis = GlobalBasisMoc<dim>; + using SizePrefix = typename Basis::SizePrefix; + + Basis basis; + + // Create raw vector + Vector x_raw; + + // Create wrapped vector + auto x = Dune::Functions::istlVectorBackend(x_raw); + + test.require(Dune::models<Dune::Functions::Concept::VectorBackend<Basis>, decltype(x)>(), "VectorBackend concept check") + << "Object returned by istlVectorBackend() does not model the VectorBackend concept"; + + // Resize wrapped vector using basis + x.resize(basis); + + // Derive size information from vector + test.require(x_raw.size() == basis.size(SizePrefix{}), "resize check") + << "x_raw.size() is " << x_raw.size() << " but should be " << basis.size(SizePrefix{}); + + test.require(x_raw[_0].size() == basis.size(SizePrefix{0}), "resize check") + << "x_raw[_0].size() is " << x_raw[_0].size() << " but should be " << basis.size(SizePrefix{0}); + + for (std::size_t i=0; i<basis.size({0}); ++i) + test.require(x_raw[_0][i].size() == basis.size(SizePrefix{0,i}), "resize check") + << "x_raw[_0][" << i << "].size() is " << x_raw[_0][i].size() << " but should be " << basis.size(SizePrefix{0,i}); + + test.require(x_raw[_1].size() == basis.size(SizePrefix{1}), "resize check") + << "x_raw[_1].size() is " << x_raw[_0].size() << " but should be " << basis.size(SizePrefix{1}); + + + // Assign values to each vector entry + for (std::size_t i=0; i<x_raw[_0].size(); ++i) + for (std::size_t j=0; j<x_raw[_0][i].size(); ++j) + x[MultiIndex{{0, i, j}}] = 0+i+j; + for (std::size_t i=0; i<x_raw[_1].size(); ++i) + x[MultiIndex{{1, i}}] = 1+i; + + + // Access vector entries via const reference + const auto& x_const = x; + for (std::size_t i=0; i<x_raw[_0].size(); ++i) + for (std::size_t j=0; j<x_raw[_0][i].size(); ++j) + { + test.check(x_const[MultiIndex{{0, i, j}}] == Coefficient(0+i+j)) + << "x[{0," << i << "," << j << "}] contains wrong value"; + } + for (std::size_t i=0; i<x_raw[_1].size(); ++i) + { + test.check(x_const[MultiIndex{{1, i}}] == Coefficient(1+i)) + << "x[{1," << i << "}] contains wrong value"; + } + + return test; +} + + +int main (int argc, char *argv[]) try +{ + // Set up MPI, if available + MPIHelper::instance(argc, argv); + + /////////////////////////////////// + // Generate the grid + /////////////////////////////////// + + + Dune::TestSuite test; + { + using VelocityVector = std::vector<std::vector<double>>; + using PressureVector = std::vector<double>; + using Coefficient = double; + using Vector = Dune::TupleVector<VelocityVector, PressureVector>; + using MultiIndex = ReservedVector<std::size_t, 3>; + test.subTest(checkHierarchicVector<Vector, Coefficient, 2, MultiIndex>("TV<V<V<double>>, V<double>>")); + } + + { + using VelocityVector = std::vector<Dune::BlockVector<Dune::FieldVector<double,1>>>; + using PressureVector = std::vector<Dune::FieldVector<double,1>>; + using Coefficient = double; + using Vector = Dune::TupleVector<VelocityVector, PressureVector>; + using MultiIndex = ReservedVector<std::size_t, 3>; + test.subTest(checkHierarchicVector<Vector, Coefficient, 2, MultiIndex>("TV<V<BV<FV<double,1>>>, V<FV<doule,1>>>")); + } + +// { +// using VelocityVector = std::vector<std::vector<Dune::FieldVector<double,3>>>; +// using PressureVector = std::vector<Dune::FieldVector<double,3>>; +// using Coefficient = Dune::FieldVector<double,3>; +// using Vector = Dune::TupleVector<VelocityVector, PressureVector>; +// using MultiIndex = ReservedVector<std::size_t, 3>; +// test.subTest(checkHierarchicVector<Vector, Coefficient, 2, MultiIndex>("TV<V<V<FV<double,3>>>, V<FV<double,3>>>")); +// } + + { + static const std::size_t dim = 5; + using VelocityVector = std::vector<std::array<Dune::FieldVector<double,1>,dim>>; + using PressureVector = std::vector<double>; + using Coefficient = double; + using Vector = Dune::TupleVector<VelocityVector, PressureVector>; + using MultiIndex = ReservedVector<std::size_t, 3>; + test.subTest(checkHierarchicVector<Vector, Coefficient, dim, MultiIndex>("TV<V<A<FV<double,1>,5>>, V<double>>")); + } + + { + static const std::size_t dim = 5; + using VelocityVector = Dune::BlockVector<Dune::FieldVector<double,dim>>; + using PressureVector = Dune::BlockVector<Dune::FieldVector<double,1>>; + using Coefficient = double; + using Vector = Dune::MultiTypeBlockVector<VelocityVector, PressureVector>; + using MultiIndex = ReservedVector<std::size_t, 3>; + test.subTest(checkHierarchicVector<Vector, Coefficient, dim, MultiIndex>("MTBV<BV<FV<double,5>>, BV<FV<double,1>>>")); + } + + { + static const std::size_t dim = 3; + using VelocityVector = std::vector<Dune::MultiTypeBlockVector<Dune::FieldVector<double,1>, double, Dune::FieldVector<double,1>>>; + using PressureVector = Dune::BlockVector<Dune::FieldVector<double,1>>; + using Coefficient = double; + using Vector = Dune::MultiTypeBlockVector<VelocityVector, PressureVector>; + using MultiIndex = ReservedVector<std::size_t, 3>; + test.subTest(checkHierarchicVector<Vector, Coefficient, dim, MultiIndex>("MTBV<V<MTBV<FV<double,1>, double, FV<double,1>>>, BV<FV<double,1>>")); + } + + + return test.exit(); +} +// Error handling +catch (Exception e) { + std::cout << e << std::endl; + return 1; +} -- GitLab