[dune-functions] [Dune-functions-commit] [Commit] dune-functions - 1ab2f22: [test] Do more testing of HierarchicVectorWrapper

Carsten Gräser graeser at mi.fu-berlin.de
Thu Sep 24 00:34:01 CEST 2015


Hi Oliver,
the HierarchicalVectorWrapper does now actually work with nested
multi-type containers with non-constant depth. As discussed we must
assume that the coefficients associated with single global basis
functions can be cast into a single coefficient type.

The latter must be provided explicitly. If the default value
'void' is used for this, the old implementation based on
uniform multi-indices with constant size drops in. This should
however be changed to a single implementation where the coefficient
type is derived if possible.

Anyway you should now be able to use things like

  MultiTypeBlockVector<
    BlockVector<FieldVector<T,dim>>,
    BlockVector<FieldVector<T,1>>

with non-uniform indices of the form

  [0,0,0]
  ...
  [0,0,dim-1]
  ...
  [0,size(PQ2Basis)-1,dim-1]
  [1,0]
  ...
  [1,size(PQ1Basis)-1]

here the dof coefficients are either T or FieldVector<T,1>
such that you have to provide T as coefficient type.

For your example to work, we may have to remove the
implicit construction of a HierarchicWrapperVector
with defaukt coefficient type from interpolate,
because it may not compile with this vector.
Please report your result. I'm curious.

Best,
Carsten

Am 24.09.2015 um 00:19 schrieb Carsten Gräser:
> New commit, appeared at Thu Sep 24 00:19:11 2015 +0200
> as part of the following ref changes:
> 
>     branch refs/heads/master    updated from ac36bb9 -> 1ab2f22
> 
> Browsable version: http://cgit.dune-project.org/repositories/dune-functions/commit/?id=1ab2f2258cf9065567658d9ce8c61024e3d38c39
> 
> ======================================================================
> 
> commit 1ab2f2258cf9065567658d9ce8c61024e3d38c39
> Author: Carsten Gräser <graeser at mi.fu-berlin.de>
> Date:   Thu Sep 24 00:17:49 2015 +0200
> 
>     [test] Do more testing of HierarchicVectorWrapper
>     
>     It now actually works with hybrid multi-type containers.
>     Please have a look at the test for examples of suitable
>     containers
> 
>  .../test/hierarchicvectorwrappertest.cc            | 192 +++++++++++++++++----
>  1 file changed, 163 insertions(+), 29 deletions(-)
> 
> 
> 
> diff --git a/dune/functions/functionspacebases/test/hierarchicvectorwrappertest.cc b/dune/functions/functionspacebases/test/hierarchicvectorwrappertest.cc
> index c3480ae..6962551 100644
> --- a/dune/functions/functionspacebases/test/hierarchicvectorwrappertest.cc
> +++ b/dune/functions/functionspacebases/test/hierarchicvectorwrappertest.cc
> @@ -136,65 +136,199 @@ public:
>  };
>  
>  
> -
> -int main (int argc, char *argv[]) try
> +class TestResult
>  {
> -  // Set up MPI, if available
> -  MPIHelper::instance(argc, argv);
>  
> -  ///////////////////////////////////
> -  //   Generate the grid
> -  ///////////////////////////////////
> +  class TestStream : public std::ostringstream
> +  {
> +  public:
>  
> -  static const int dim = 2;
> +    TestStream(bool condition, bool required) :
> +      condition_(condition),
> +      required_(required)
> +    {}
>  
> -  using namespace Dune::TypeTree::Indices;
> +    TestStream(const TestStream& other) :
> +      condition_(other.condition_),
> +      required_(other.required_)
> +    {
> +      (*this) << other.str();
> +      other.condition_ = true;
> +    }
>  
> -//  using VelocityVector = std::vector<std::array<double,dim>>;
> -//  using PressureVector = std::vector<double>;
> +    ~TestStream()
> +    {
> +      if (not condition_)
> +      {
> +        if (required_)
> +        {
> +          std::cout << "Required check failed : " << this->str() << std::endl;
> +          DUNE_THROW(Dune::Exception, "Required check failed : " << this->str());
> +        }
> +        else
> +          std::cout << "Check failed : " << this->str() << std::endl;
> +      }
> +    }
>  
> -  using VelocityVector = std::vector<std::vector<double>>;
> -  using PressureVector = std::vector<double>;
> +  private:
> +    mutable bool condition_;
> +    bool required_;
> +  };
>  
> -  using Vector = TupleVector<VelocityVector, PressureVector>;
> +public:
>  
> -  Vector x_raw;
> +  TestResult() :
> +    result_(true)
> +  {}
> +
> +  TestStream check(bool condition)
> +  {
> +    result_ &= condition;
> +    return TestStream(condition, false);
> +  }
> +
> +  TestStream require(bool condition)
> +  {
> +    result_ &= condition;
> +    return TestStream(condition, true);
> +  }
> +
> +  operator const bool& () const
> +  {
> +    return result_;
> +  }
> +
> +  operator bool& ()
> +  {
> +    return result_;
> +  }
> +
> +private:
> +  bool result_;
> +};
> +
> +
> +
> +template<class Vector, class Coefficient, std::size_t dim, class MultiIndex>
> +bool checkHierarchicVector()
> +{
> +  TestResult result;
> +
> +  using namespace Dune::TypeTree::Indices;
> +  using SizeInfo = HybridSizeInfoDummy<dim>;
> +  using SizePrefix = typename SizeInfo::SizePrefix;
> +
> +  SizeInfo sizeInfo;
>  
> -  auto x = Dune::Functions::HierarchicVectorWrapper<decltype(x_raw),double>(x_raw);
> -//  auto x = Dune::Functions::hierarchicVector(x_raw);
> +  // Create raw vector
> +  Vector x_raw;
>  
> -  HybridSizeInfoDummy<dim> sizeInfo;
> +  // Create wrapped vector
> +  Dune::Functions::HierarchicVectorWrapper<Vector, Coefficient> x(x_raw);
>  
> +  // Resize wrapped vector using sizeInfo
>    x.resize(sizeInfo);
>  
> -  using MultiIndex = ReservedVector<std::size_t, 3>;
> -//  using MultiIndex = std::array<std::size_t, 3>;
> +  // Derive size information from vector
> +  result.require(x_raw.size() == sizeInfo(SizePrefix{}))
> +    << "x_raw.size() is " << x_raw.size() << " but should be " << sizeInfo(SizePrefix{});
>  
> +  result.require(x_raw[_0].size() == sizeInfo(SizePrefix{0}))
> +    << "x_raw[_0].size() is " << x_raw[_0].size() << " but should be " << sizeInfo(SizePrefix{0});
>  
> -  std::cout << "size()       " << x_raw.size() << std::endl;
> -  std::cout << "size({0})    " << x_raw[_0].size() << std::endl;
>    for (std::size_t i=0; i<sizeInfo({0}); ++i)
> -    std::cout << "size({0," << i << "})  " << x_raw[_0][i].size() << std::endl;
> -  std::cout << "size({1})    " << x_raw[_1].size() << std::endl;
> +    result.require(x_raw[_0][i].size() == sizeInfo(SizePrefix{0,i}))
> +      << "x_raw[_0][" << i << "].size() is " << x_raw[_0][i].size() << " but should be " << sizeInfo(SizePrefix{0,i});
>  
> +  result.require(x_raw[_1].size() == sizeInfo(SizePrefix{1}))
> +    << "x_raw[_1].size() is " << x_raw[_0].size() << " but should be " << sizeInfo(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)
> +    {
>        std::cout << "x[{0," << i << "," << j << "}] = " << x_const[MultiIndex{{0, i, j}}] << std::endl;
> -
> +//      result.check(x[MultiIndex{{0, i, j}}] == 0.0+i+j)
> +//        << "x[{0," << i << "," << j << "}] contains wrong value";
> +    }
>    for (std::size_t i=0; i<x_raw[_1].size(); ++i)
> -      std::cout << "x[{1," << i << "}] = " << x_const[MultiIndex{{1, i}}] << std::endl;
> +  {
> +    std::cout << "x[{1," << i << "}] = " << x_const[MultiIndex{{1, i}}] << std::endl;
> +//    result.check(x[MultiIndex{{1, i}}] == 1.0+i)
> +//      << "x[{1," << i << "}] contains wrong value";
> +  }
> +    result.check(false)
> +      << "x[{1," << 1 << "}] contains wrong value";
> +  return result;
> +}
> +
> +
> +int main (int argc, char *argv[]) try
> +{
> +  // Set up MPI, if available
> +  MPIHelper::instance(argc, argv);
> +
> +  ///////////////////////////////////
> +  //   Generate the grid
> +  ///////////////////////////////////
> +
> +
> +  TestResult result;
> +  {
> +    using VelocityVector = std::vector<std::vector<double>>;
> +    using PressureVector = std::vector<double>;
> +    using Coefficient = double;
> +    using Vector = TupleVector<VelocityVector, PressureVector>;
> +    using MultiIndex = ReservedVector<std::size_t, 3>;
> +    result.check(checkHierarchicVector<Vector, Coefficient, 2, MultiIndex>())
> +      << "Test with " << Dune::className<Vector>() << " failed";
> +  }
> +
> +  {
> +    using VelocityVector = std::vector<Dune::BlockVector<Dune::FieldVector<double,1>>>;
> +    using PressureVector = std::vector<Dune::FieldVector<double,1>>;
> +    using Coefficient = double;
> +    using Vector = TupleVector<VelocityVector, PressureVector>;
> +    using MultiIndex = ReservedVector<std::size_t, 3>;
> +    result.check(checkHierarchicVector<Vector, Coefficient, 2, MultiIndex>())
> +      << "Test with " << Dune::className<Vector>() << " failed";
> +  }
> +
> +  {
> +    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 = TupleVector<VelocityVector, PressureVector>;
> +    using MultiIndex = ReservedVector<std::size_t, 3>;
> +    result.check(checkHierarchicVector<Vector, Coefficient, 2, MultiIndex>())
> +      << "Test with " << Dune::className<Vector>() << " failed";
> +  }
> +
> +  {
> +    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 = TupleVector<VelocityVector, PressureVector>;
> +    using MultiIndex = ReservedVector<std::size_t, 3>;
> +    result.check(checkHierarchicVector<Vector, Coefficient, dim, MultiIndex>())
> +      << "Test with " << Dune::className<Vector>() << " failed";
> +  }
> +
> +  if (not result)
> +    std::cout << "Test failed" << std::endl;
> +
> +  return result ? 0 : 1;
>  
>  }
>  // Error handling
> 
> _______________________________________________
> Dune-functions-commit mailing list
> Dune-functions-commit at dune-project.org
> http://lists.dune-project.org/mailman/listinfo/dune-functions-commit
> 
	

-- 
Prof. Dr. Carsten Gräser
Freie Universität Berlin
Institut für Mathematik
Arnimallee 6
14195 Berlin, Germany
phone: +49 30 838 72637
fax  : +49 30 838 472637
email: graeser at mi.fu-berlin.de
URL  : http://page.mi.fu-berlin.de/graeser

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <https://lists.dune-project.org/pipermail/dune-functions/attachments/20150924/cfae86f1/attachment.sig>


More information about the dune-functions mailing list