Skip to content
Snippets Groups Projects
Commit a30be1c8 authored by graeser's avatar graeser
Browse files

[cleanup] Hide FlatVectorBackend in favour of flatVectorView()

* Hide the old implementation class FlatVectorBackend in
  namespace Impl::. It was never documented anyway.
* Add a new class FlatVectorView. In contrast to the old one,
  this behaves like a (view-) value providing a very slim
  flat-vector-like interface instead of odd static methods.
* To be flexible FlatVectorView is also hidden in Impl::
  Instead we only expose factory methods:
* Add factory methods flatVectorView() creating the view
  objects. When passing a const/mutable l-value reference
  the returned object will store a pointer to the underlying
  container. If the passed container is an r-value reference
  the object will be stored by value inside of the view.
  This is necessary to support proxy objects.
parent 2aade3f1
No related branches found
No related tags found
No related merge requests found
......@@ -11,7 +11,7 @@ install(FILES
defaultlocalview.hh
defaultnodetorangemap.hh
flatmultiindex.hh
flatvectorbackend.hh
flatvectorview.hh
hierarchicvectorwrapper.hh
interpolate.hh
lagrangebasis.hh
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_FLATVECTORBACKEND_HH
#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_FLATVECTORBACKEND_HH
#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_FLATVECTORVIEW_HH
#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_FLATVECTORVIEW_HH
#include <dune/common/concept.hh>
......@@ -13,6 +13,7 @@
namespace Dune {
namespace Functions {
namespace Impl {
......@@ -75,8 +76,130 @@ struct FlatVectorBackend<typename Dune::FieldMatrix<K, n, m> >
};
template<class T>
class FlatVectorView
{
using Backend = FlatVectorBackend<std::decay_t<T>>;
public:
FlatVectorView(T& t) :
t_(&t)
{}
auto size() const
{
return Backend::size(*t_);
}
template<class Index>
decltype(auto) operator[](const Index& i) const
{
return Backend::getEntry(*t_, i);
}
template<class Index>
decltype(auto) operator[](const Index& i)
{
return Backend::getEntry(*t_, i);
}
private:
T* t_;
};
template<class T>
class FlatVectorView<T&&>
{
using Backend = FlatVectorBackend<std::decay_t<T>>;
public:
FlatVectorView(T&& t) :
t_(std::move(t))
{}
auto size() const
{
return Backend::size(t_);
}
template<class Index>
decltype(auto) operator[](const Index& i) const
{
return Backend::getEntry(t_, i);
}
template<class Index>
decltype(auto) operator[](const Index& i)
{
return Backend::getEntry(t_, i);
}
private:
T t_;
};
} // namespace Impl
/**
* \brief Create flat vector view of passed mutable container
*
* When passed a nested container, the resulting value is
* a flat-vector-like view object. It provides an operator[]
* method to access all entries of the underlying nested
* container using flat consecutive indices and a size()
* method to compute the corresponding total size.
*
* This method will create a view object storing a pointer
* to the passed mutable container.
*/
template<class T>
auto flatVectorView(T& t)
{
return Impl::FlatVectorView<T>(t);
}
/**
* \brief Create flat vector view of passed const container
*
* When passed a nested container, the resulting value is
* a flat-vector-like view object. It provides an operator[]
* method to access all entries of the underlying nested
* container using flat consecutive indices and a size()
* method to compute the corresponding total size.
*
* This method will create a view object storing a pointer
* to the passed const container.
*/
template<class T>
auto flatVectorView(const T& t)
{
return Impl::FlatVectorView<const T>(t);
}
/**
* \brief Create flat vector view of passed container temporary
*
* When passed a nested container, the resulting value is
* a flat-vector-like view object. It provides an operator[]
* method to access all entries of the underlying nested
* container using flat consecutive indices and a size()
* method to compute the corresponding total size.
*
* This method will create a 'view' object storing the
* provided temporary container by value.
*/
template<class T>
auto flatVectorView(T&& t)
{
return Impl::FlatVectorView<T&&>(t);
}
} // namespace Dune::Functions
} // namespace Dune
#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_FLATVECTORBACKEND_HH
#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_FLATVECTORVIEW_HH
......@@ -19,7 +19,7 @@
#include <dune/functions/functionspacebases/hierarchicvectorwrapper.hh>
#include <dune/functions/functionspacebases/sizeinfo.hh>
#include <dune/functions/functionspacebases/flatvectorbackend.hh>
#include <dune/functions/functionspacebases/flatvectorview.hh>
#include <dune/functions/functionspacebases/defaultnodetorangemap.hh>
#include <dune/typetree/traversal.hh>
......@@ -84,9 +84,6 @@ public:
using GlobalDomain = typename Element::Geometry::GlobalCoordinate;
using CoefficientBlock = typename std::decay<decltype(std::declval<HierarchicVector>()[std::declval<MultiIndex>()])>::type;
using BitVectorBlock = typename std::decay<decltype(std::declval<HierarchicBitVector>()[std::declval<MultiIndex>()])>::type;
LocalInterpolateVisitor(const B& basis, HV& coeff, const HBV& bitVector, const LF& localF, const LocalIndexSet& localIndexSet, const NodeToRangeEntry& nodeToRangeEntry) :
vector_(coeff),
localF_(localF),
......@@ -120,9 +117,7 @@ public:
std::size_t j=0;
auto localFj = [&](const LocalDomain& x){
const auto& y = localF_(x);
const auto& y_node = nodeToRangeEntry_(node, y);
using FunctionRange = typename std::decay<decltype(y_node)>::type;
return FlatVectorBackend<FunctionRange>::getEntry(y_node, j);
return flatVectorView(nodeToRangeEntry_(node, y))[j];
};
using FunctionFromCallable = typename Dune::Functions::FunctionFromCallable<FiniteElementRange(LocalDomain), decltype(localFj), FunctionBaseClass>;
......@@ -134,7 +129,7 @@ public:
// We loop over j defined above and thus over the components of the
// range type of localF_.
auto blockSize = FlatVectorBackend<CoefficientBlock>::size(vector_[localIndexSet_.index(0)]);
auto blockSize = flatVectorView(vector_[localIndexSet_.index(0)]).size();
for(j=0; j<blockSize; ++j)
{
......@@ -144,13 +139,11 @@ public:
for (size_t i=0; i<fe.localBasis().size(); ++i)
{
auto multiIndex = localIndexSet_.index(node.localIndex(i));
const auto& bitVectorBlock = bitVector_[multiIndex];
const auto& interpolateHere = FlatVectorBackend<BitVectorBlock>::getEntry(bitVectorBlock,j);
if (interpolateHere)
auto bitVectorBlock = flatVectorView(bitVector_[multiIndex]);
if (bitVectorBlock[j])
{
auto&& vectorBlock = vector_[multiIndex];
FlatVectorBackend<CoefficientBlock>::getEntry(vectorBlock, j) = interpolationCoefficients[i];
auto vectorBlock = flatVectorView(vector_[multiIndex]);
vectorBlock[j] = interpolationCoefficients[i];
}
}
}
......@@ -180,7 +173,7 @@ protected:
*
* Notice that this will only work if the range type of f and
* the block type of coeff are compatible and supported by
* FlatVectorBackend.
* flatVectorView.
*
* \param basis Global function space basis of discrete function space
* \param treePath Tree path specifying the part of the ansatz tree to use
......@@ -262,7 +255,7 @@ void interpolateTree(const B& basis, const TypeTree::HybridTreePath<TreeIndices.
*
* Notice that this will only work if the range type of f and
* the block type of coeff are compatible and supported by
* FlatVectorBackend.
* flatVectorView.
*
* \param basis Global function space basis of discrete function space
* \param treePath Tree path specifying the part of the ansatz tree to use
......@@ -301,7 +294,7 @@ namespace Imp {
*
* Notice that this will only work if the range type of f and
* the block type of coeff are compatible and supported by
* FlatVectorBackend.
* flatVectorView.
*
* \param basis Global function space basis of discrete function space
* \param coeff Coefficient vector to represent the interpolation
......@@ -323,7 +316,7 @@ void interpolate(const B& basis, C&& coeff, const F& f, const BV& bitVector)
*
* Notice that this will only work if the range type of f and
* the block type of coeff are compatible and supported by
* FlatVectorBackend.
* flatVectorView.
*
* This function will only work, if the local ansatz tree of
* the basis is trivial, i.e., a single leaf node.
......@@ -346,7 +339,7 @@ void interpolate(const B& basis, C&& coeff, const F& f)
*
* Notice that this will only work if the range type of f and
* the block type of corresponding coeff entries are compatible
* and supported by FlatVectorBackend.
* and supported by flatVectorView.
*
* \param basis Global function space basis of discrete function space
* \param treePath Tree path specifying the part of the ansatz tree to use
......
......@@ -8,7 +8,7 @@
#include <dune/common/shared_ptr.hh>
#include <dune/functions/functionspacebases/defaultnodetorangemap.hh>
#include <dune/functions/functionspacebases/flatvectorbackend.hh>
#include <dune/functions/functionspacebases/flatvectorview.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/functions/gridfunctions/gridfunction.hh>
#include <dune/functions/common/treedata.hh>
......@@ -40,13 +40,13 @@ namespace Functions {
* V the value of this basis function at the evaluation point. Notice
* that both may be scalar, vector, matrix, or general container valued.
*
* 2.Each entry of C is associated with a flat index j via FlatVectorBackend.
* 2.Each entry of C is associated with a flat index j via flatVectorView.
* This is normally a lexicographic index. The total scalar dimension according
* to those flat indices is dim(C).
* 3.Each entry of V is associated with a flat index k via FlatVectorBackend.
* 3.Each entry of V is associated with a flat index k via flatVectorView.
* This is normally a lexicographic index. The total scalar dimension according
* to those flat indices dim(V).
* 4.Each entry of RE is associated with a flat index k via FlatVectorBackend.
* 4.Each entry of RE is associated with a flat index k via flatVectorView.
* This is normally a lexicographic index. The total scalar dimension according
* to those flat indices dim(RE).
* 5.Via those flat indices we now interpret C,V, and RE as vectors and compute the diadic
......@@ -117,9 +117,7 @@ public:
template<typename Node, typename TreePath>
void leaf(Node& node, TreePath treePath)
{
using LocalBasisRange = typename Node::FiniteElement::Traits::LocalBasisType::Traits::RangeType;
using MultiIndex = typename LocalIndexSet::MultiIndex;
using CoefficientBlock = typename std::decay<decltype(std::declval<Vector>()[std::declval<MultiIndex>()])>::type;
using RangeBlock = typename std::decay<decltype(nodeToRangeEntry_(node, y_))>::type;
auto&& fe = node.finiteElement();
......@@ -129,7 +127,7 @@ public:
localBasis.evaluateFunction(x_, shapeFunctionValues);
// Get range entry associated to this node
auto&& re = nodeToRangeEntry_(node, y_);
auto re = flatVectorView(nodeToRangeEntry_(node, y_));
for (size_type i = 0; i < localBasis.size(); ++i)
......@@ -137,26 +135,25 @@ public:
auto&& multiIndex = localIndexSet_.index(node.localIndex(i));
// Get coefficient associated to i-th shape function
auto&& c = coefficients_[multiIndex];
auto c = flatVectorView(coefficients_[multiIndex]);
// Get value of i-th shape function
auto&& v = shapeFunctionValues[i];
auto v = flatVectorView(shapeFunctionValues[i]);
// Notice that the range entry re, the coefficient c, and the shape functions
// value v may all be scalar, vector, matrix, or general container valued.
// The matching of their entries is done via the multistage procedure described
// in the class documentation of DiscreteGlobalBasisFunction.
auto dimC = FlatVectorBackend<CoefficientBlock>::size(c);
auto dimV = FlatVectorBackend<LocalBasisRange>::size(v);
assert(dimC*dimV == FlatVectorBackend<RangeBlock>::size(re));
auto&& dimC = c.size();
auto dimV = v.size();
assert(dimC*dimV == re.size());
for(size_type j=0; j<dimC; ++j)
{
auto&& c_j = FlatVectorBackend<CoefficientBlock>::getEntry(c, j);
auto&& c_j = c[j];
for(size_type k=0; k<dimV; ++k)
{
auto&& v_k = FlatVectorBackend<LocalBasisRange>::getEntry(v, k);
FlatVectorBackend<RangeBlock>::getEntry(re, j*dimV + k) += c_j*v_k;
}
re[j*dimV + k] += c_j*v[k];
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment