Commit 6be0913f authored by Praetorius, Simon's avatar Praetorius, Simon
Browse files

Merge branch 'issue/allow_containers_in_discretefunction' into 'master'

Allow std containers as coefficients in DiscreteFunction and allow DefaultGlobalBasis

See merge request !248
parents f9a94a4e 2d132a0e
...@@ -62,12 +62,16 @@ namespace AMDiS ...@@ -62,12 +62,16 @@ namespace AMDiS
} }
/// Return a const view to a oldSolution component /// Return a const view to a oldSolution component
template <class... Indices> /**
* \tparam Range The range type return by evaluating the view in coordinates. If not specified,
* it is automatically selected using \ref RangeType_t template.
**/
template <class Range = void, class... Indices>
auto oldSolution(Indices... ii) const auto oldSolution(Indices... ii) const
{ {
test_exit_dbg(bool(oldSolution_), test_exit_dbg(bool(oldSolution_),
"OldSolution need to be created. Call initialize with INIT_UH_OLD."); "OldSolution need to be created. Call initialize with INIT_UH_OLD.");
return valueOf(*oldSolution_, ii...); return valueOf<Range>(*oldSolution_, ii...);
} }
/// Implementation of \ref ProblemTimeInterface::transferInitialSolution(). /// Implementation of \ref ProblemTimeInterface::transferInitialSolution().
......
...@@ -393,19 +393,27 @@ namespace AMDiS ...@@ -393,19 +393,27 @@ namespace AMDiS
/// Return a mutable view to a solution component /// Return a mutable view to a solution component
template <class... Indices> /**
* \tparam Range The range type return by evaluating the view in coordinates. If not specified,
* it is automatically selected using \ref RangeType_t template.
**/
template <class Range = void, class... Indices>
auto solution(Indices... ii) auto solution(Indices... ii)
{ {
assert(bool(solution_) && "You have to call initialize() before."); assert(bool(solution_) && "You have to call initialize() before.");
return valueOf(*solution_, ii...); return valueOf<Range>(*solution_, ii...);
} }
/// Return a const view to a solution component /// Return a const view to a solution component
template <class... Indices> /**
* \tparam Range The range type return by evaluating the view in coordinates. If not specified,
* it is automatically selected using \ref RangeType_t template.
**/
template <class Range = void, class... Indices>
auto solution(Indices... ii) const auto solution(Indices... ii) const
{ {
assert(bool(solution_) && "You have to call initialize() before."); assert(bool(solution_) && "You have to call initialize() before.");
return valueOf(*solution_, ii...); return valueOf<Range>(*solution_, ii...);
} }
......
...@@ -3,14 +3,16 @@ ...@@ -3,14 +3,16 @@
#include <optional> #include <optional>
#include <vector> #include <vector>
#include <dune/common/ftraits.hh>
#include <dune/common/typeutilities.hh>
#include <dune/functions/common/defaultderivativetraits.hh> #include <dune/functions/common/defaultderivativetraits.hh>
#include <dune/functions/functionspacebases/defaultnodetorangemap.hh>
#include <dune/functions/functionspacebases/flatvectorview.hh> #include <dune/functions/functionspacebases/flatvectorview.hh>
#include <dune/functions/gridfunctions/gridviewentityset.hh> #include <dune/functions/gridfunctions/gridviewentityset.hh>
#include <dune/typetree/childextraction.hh> #include <dune/typetree/childextraction.hh>
#include <amdis/common/Tags.hpp> #include <amdis/common/Tags.hpp>
#include <amdis/functions/NodeCache.hpp> #include <amdis/functions/NodeCache.hpp>
#include <amdis/linearalgebra/Access.hpp>
#include <amdis/typetree/FiniteElementType.hpp> #include <amdis/typetree/FiniteElementType.hpp>
#include <amdis/typetree/RangeType.hpp> #include <amdis/typetree/RangeType.hpp>
#include <amdis/typetree/TreePath.hpp> #include <amdis/typetree/TreePath.hpp>
...@@ -22,28 +24,28 @@ namespace AMDiS ...@@ -22,28 +24,28 @@ namespace AMDiS
/** /**
* \ingroup GridFunctions * \ingroup GridFunctions
* *
* \tparam Coeff Const or mutable coefficient type of the DOFVector * \tparam Coeff Const or mutable coefficient vector
* \tparam GB Thy type of the global basis * \tparam GB The type of the global basis
* \tparam TreePath A realization of \ref Dune::TypeTree::HybridTreePath * \tparam TreePath A realization of \ref Dune::TypeTree::HybridTreePath
* \tparam Range The range type for th evaluation of the discrete function
* *
* **Requirements:** * **Requirements:**
* - GB models \ref Concepts::GlobalBasis * - GB models \ref Concepts::GlobalBasis
**/ **/
template <class Coeff, class GB, class TreePath> template <class Coeff, class GB, class TreePath, class Range = void>
class DiscreteFunction; class DiscreteFunction;
/// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction /// A mutable view on the subspace of a DOFVector, \relates DiscreteFunction
template <class Coeff, class GB, class TreePath> template <class Coeff, class GB, class TreePath, class R>
class DiscreteFunction class DiscreteFunction
: public DiscreteFunction<Coeff const,GB,TreePath> : public DiscreteFunction<Coeff const,GB,TreePath,R>
{ {
using Self = DiscreteFunction<Coeff,GB,TreePath>; using Self = DiscreteFunction<Coeff,GB,TreePath,R>;
using Super = DiscreteFunction<Coeff const,GB,TreePath>; using Super = DiscreteFunction<Coeff const,GB,TreePath,R>;
using Coefficients = Coeff; using Coefficients = Coeff;
using GlobalBasis = GB; using GlobalBasis = GB;
using ValueType = typename Coeff::value_type;
public: public:
/// Constructor. Stores a pointer to the mutable `dofvector`. /// Constructor. Stores a pointer to the mutable `dofvector`.
...@@ -54,16 +56,17 @@ namespace AMDiS ...@@ -54,16 +56,17 @@ namespace AMDiS
{} {}
template <class... Path> template <class... Path>
DiscreteFunction(Coefficients& dofVector, std::shared_ptr<GlobalBasis const> const& basis, Path... path) DiscreteFunction(Coefficients& coefficients, std::shared_ptr<GlobalBasis const> const& basis, Path... path)
: DiscreteFunction(dofVector, *basis, path...) : DiscreteFunction(coefficients, *basis, path...)
{} {}
/// Construct a DiscreteFunction directly from a DOFVector /// Construct a DiscreteFunction directly from a DOFVector
template <class DV, class... Path, template <class DV, class... Path,
Dune::disableCopyMove<DiscreteFunction,DV> = 0,
class Coeff_ = TYPEOF(std::declval<DV>().coefficients()), class Coeff_ = TYPEOF(std::declval<DV>().coefficients()),
class GB_ = TYPEOF(*std::declval<DV>().basis())> class GB_ = TYPEOF(std::declval<DV>().basis())>
DiscreteFunction(DV&& dofVector, Path... path) explicit DiscreteFunction(DV&& dofVector, Path... path)
: DiscreteFunction(dofVector.coefficients(), *dofVector.basis(), path...) : DiscreteFunction(dofVector.coefficients(), dofVector.basis(), path...)
{} {}
public: public:
...@@ -125,11 +128,11 @@ namespace AMDiS ...@@ -125,11 +128,11 @@ namespace AMDiS
/// Return the const DOFVector /// Return the const DOFVector
using Super::coefficients; using Super::coefficients;
template <class... Indices> template <class Range = void, class... Indices>
auto child(Indices... ii) auto child(Indices... ii)
{ {
auto tp = cat(this->treePath_, makeTreePath(ii...)); auto tp = cat(this->treePath_, makeTreePath(ii...));
return DiscreteFunction<Coeff, GB, TYPEOF(makeTreePath(tp))>{*mutableCoeff_, this->basis(), tp}; return DiscreteFunction<Coeff, GB, TYPEOF(makeTreePath(tp)), Range>{*mutableCoeff_, this->basis(), tp};
} }
using Super::child; using Super::child;
...@@ -139,22 +142,20 @@ namespace AMDiS ...@@ -139,22 +142,20 @@ namespace AMDiS
}; };
/// A Const DiscreteFunction /// A Const DiscreteFunction
template <class Coeff, class GB, class TreePath> template <class Coeff, class GB, class TreePath, class R>
class DiscreteFunction<Coeff const,GB,TreePath> class DiscreteFunction<Coeff const,GB,TreePath,R>
{ {
private: private:
using Coefficients = std::remove_const_t<Coeff>; using Coefficients = std::remove_const_t<Coeff>;
using GlobalBasis = GB; using GlobalBasis = GB;
using LocalView = typename GlobalBasis::LocalView; using LocalView = typename GlobalBasis::LocalView;
using GridView = typename GlobalBasis::GridView; using GridView = typename GlobalBasis::GridView;
using ValueType = typename Coefficients::value_type;
using Coefficient = TYPEOF(std::declval<Traits::Access>()(std::declval<Coeff const>(), std::declval<typename GB::MultiIndex>()));
using Tree = typename GlobalBasis::LocalView::Tree; using Tree = typename GlobalBasis::LocalView::Tree;
using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>; using SubTree = typename Dune::TypeTree::ChildForTreePath<Tree, TreePath>;
using TreeCache = NodeCache_t<Tree>;
using SubTreeCache = typename Dune::TypeTree::ChildForTreePath<TreeCache, TreePath>;
public: public:
/// Set of entities the DiscreteFunction is defined on /// Set of entities the DiscreteFunction is defined on
using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>; using EntitySet = Dune::Functions::GridViewEntitySet<GridView, 0>;
...@@ -162,14 +163,14 @@ namespace AMDiS ...@@ -162,14 +163,14 @@ namespace AMDiS
/// Global coordinates of the EntitySet /// Global coordinates of the EntitySet
using Domain = typename EntitySet::GlobalCoordinate; using Domain = typename EntitySet::GlobalCoordinate;
/// Range type of this DiscreteFunction /// Range type of this DiscreteFunction. If R=void deduce the Range automatically, using RangeType_t
using Range = RangeType_t<SubTree,ValueType>; using Range = std::conditional_t<std::is_same_v<R,void>, RangeType_t<SubTree,Coefficient>, R>;
/// \brief This GridFunction has no derivative function, it can be created /// \brief This GridFunction has no derivative function, it can be created
/// by \ref DiscreteGridFunction. /// by \ref DiscreteGridFunction.
enum { hasDerivative = false }; enum { hasDerivative = false };
public: private:
/// A LocalFunction representing the localfunction and derivative of the DOFVector on a bound element /// A LocalFunction representing the localfunction and derivative of the DOFVector on a bound element
template <class Type> template <class Type>
class LocalFunction; class LocalFunction;
...@@ -191,9 +192,10 @@ namespace AMDiS ...@@ -191,9 +192,10 @@ namespace AMDiS
/// Construct a DiscreteFunction directly from a DOFVector /// Construct a DiscreteFunction directly from a DOFVector
template <class DV, class... Path, template <class DV, class... Path,
Dune::disableCopyMove<DiscreteFunction,DV> = 0,
class Coeff_ = TYPEOF(std::declval<DV>().coefficients()), class Coeff_ = TYPEOF(std::declval<DV>().coefficients()),
class GB_ = TYPEOF(std::declval<DV>().basis())> class GB_ = TYPEOF(std::declval<DV>().basis())>
DiscreteFunction(DV const& dofVector, Path... path) explicit DiscreteFunction(DV const& dofVector, Path... path)
: DiscreteFunction(dofVector.coefficients(), dofVector.basis(), path...) : DiscreteFunction(dofVector.coefficients(), dofVector.basis(), path...)
{} {}
...@@ -230,11 +232,11 @@ namespace AMDiS ...@@ -230,11 +232,11 @@ namespace AMDiS
return *coefficients_; return *coefficients_;
} }
template <class... Indices> template <class Range = void, class... Indices>
auto child(Indices... ii) const auto child(Indices... ii) const
{ {
auto tp = cat(this->treePath_, makeTreePath(ii...)); auto tp = cat(this->treePath_, makeTreePath(ii...));
return DiscreteFunction<Coeff const, GB, TYPEOF(makeTreePath(tp))>{*coefficients_, *basis_, tp}; return DiscreteFunction<Coeff const, GB, TYPEOF(makeTreePath(tp)), Range>{*coefficients_, *basis_, tp};
} }
protected: protected:
...@@ -247,45 +249,47 @@ namespace AMDiS ...@@ -247,45 +249,47 @@ namespace AMDiS
// deduction guides // deduction guides
template <class Coeff, class Basis, class... Path, template <class C, class Basis, class... Indices,
class TP = TYPEOF(makeTreePath(std::declval<Path>()...)),
class GB = Underlying_t<Basis>, class GB = Underlying_t<Basis>,
class TP = TYPEOF(makeTreePath(std::declval<Indices>()...)),
REQUIRES(Concepts::GlobalBasis<GB>)> REQUIRES(Concepts::GlobalBasis<GB>)>
DiscreteFunction(Coeff&, Basis const&, Path...) DiscreteFunction(C&, Basis const&, Indices...)
-> DiscreteFunction<Coeff,GB,TP>; -> DiscreteFunction<C,GB,TP>;
template <class DV, class... Path, template <class DV, class... Indices,
class Coeff = decltype(std::declval<DV>().coefficients()), class C = decltype(std::declval<DV>().coefficients()),
class GB = decltype(std::declval<DV>().basis()), class GB = decltype(std::declval<DV>().basis()),
class TP = TYPEOF(makeTreePath(std::declval<Path>()...))> class TP = TYPEOF(makeTreePath(std::declval<Indices>()...))>
DiscreteFunction(DV&, Path...) DiscreteFunction(DV&, Indices...)
-> DiscreteFunction<std::remove_reference_t<Coeff>,Underlying_t<GB>,TP>; -> DiscreteFunction<std::remove_reference_t<C>,Underlying_t<GB>,TP>;
// grid functions representing the DOFVector // grid functions representing the DOFVector
// ----------------------------------------- // -----------------------------------------
/// A Generator for the childs of a mutable \ref DiscreteFunction /// A Generator for the childs of a mutable \ref DiscreteFunction
template <class Coeff, class GB, class... Path, class... Indices> template <class Range = void, class C, class GB, class TP, class R, class... Indices>
auto valueOf(DiscreteFunction<Coeff,GB,Path...>& df, Indices... ii) auto valueOf(DiscreteFunction<C,GB,TP,R>& df, Indices... ii)
{ {
return df.child(ii...); return df.template child<Range>(ii...);
} }
/// A Generator for the childs of a const \ref DiscreteFunction /// A Generator for the childs of a const \ref DiscreteFunction
template <class Coeff, class GB, class... Path, class... Indices> template <class Range = void, class C, class GB, class TP, class R, class... Indices>
auto valueOf(DiscreteFunction<Coeff,GB,Path...> const& df, Indices... ii) auto valueOf(DiscreteFunction<C,GB,TP,R> const& df, Indices... ii)
{ {
return df.child(ii...); return df.template child<Range>(ii...);
} }
/// A Generator to transform a DOFVector into a \ref DiscreteFunction /// A Generator to transform a DOFVector into a \ref DiscreteFunction
template <class DV, class... Indices, template <class Range = void, class DV, class... Indices,
class = decltype(std::declval<DV>().coefficients()), class C = decltype(std::declval<DV>().coefficients()),
class = decltype(std::declval<DV>().basis())> class GB = decltype(std::declval<DV>().basis()),
class TP = TYPEOF(makeTreePath(std::declval<Indices>()...))>
auto valueOf(DV& dofVec, Indices... ii) auto valueOf(DV& dofVec, Indices... ii)
{ {
return DiscreteFunction{dofVec.coefficients(), dofVec.basis(), makeTreePath(ii...)}; using DF = DiscreteFunction<std::remove_reference_t<C>,Underlying_t<GB>,TP,Range>;
return DF{dofVec.coefficients(), dofVec.basis(), makeTreePath(ii...)};
} }
} // end namespace AMDiS } // end namespace AMDiS
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
namespace AMDiS { namespace AMDiS {
// Evaluate DiscreteFunction in global coordinates // Evaluate DiscreteFunction in global coordinates
template <class Coeff, class GB, class TP> template <class C, class GB, class TP, class R>
typename DiscreteFunction<Coeff const,GB,TP>::Range DiscreteFunction<Coeff const,GB,TP>:: typename DiscreteFunction<C const,GB,TP,R>::Range DiscreteFunction<C const,GB,TP,R>::
operator()(Domain const& x) const operator()(Domain const& x) const
{ {
using Grid = typename GlobalBasis::GridView::Grid; using Grid = typename GlobalBasis::GridView::Grid;
...@@ -30,9 +30,9 @@ typename DiscreteFunction<Coeff const,GB,TP>::Range DiscreteFunction<Coeff const ...@@ -30,9 +30,9 @@ typename DiscreteFunction<Coeff const,GB,TP>::Range DiscreteFunction<Coeff const
// Interpolation of GridFunction to DOFVector // Interpolation of GridFunction to DOFVector
template <class Coeff, class GB, class TP> template <class C, class GB, class TP, class R>
template <class Expr, class Tag> template <class Expr, class Tag>
void DiscreteFunction<Coeff,GB,TP>:: void DiscreteFunction<C,GB,TP,R>::
interpolate_noalias(Expr&& expr, Tag strategy) interpolate_noalias(Expr&& expr, Tag strategy)
{ {
auto const& basis = this->basis(); auto const& basis = this->basis();
...@@ -41,7 +41,7 @@ void DiscreteFunction<Coeff,GB,TP>:: ...@@ -41,7 +41,7 @@ void DiscreteFunction<Coeff,GB,TP>::
auto&& gf = makeGridFunction(FWD(expr), basis.gridView()); auto&& gf = makeGridFunction(FWD(expr), basis.gridView());
if (std::is_same_v<Tag, tag::average>) { if (std::is_same_v<Tag, tag::average>) {
VectorType_t<short,Coeff> counter(basis); VectorType_t<short,Coefficients> counter(basis);
AMDiS::interpolate(basis, coefficients(), gf, treePath, counter); AMDiS::interpolate(basis, coefficients(), gf, treePath, counter);
coefficients().forEach([&counter](auto dof, auto& coeff) coefficients().forEach([&counter](auto dof, auto& coeff)
...@@ -55,13 +55,13 @@ void DiscreteFunction<Coeff,GB,TP>:: ...@@ -55,13 +55,13 @@ void DiscreteFunction<Coeff,GB,TP>::
// Interpolation of GridFunction to DOFVector // Interpolation of GridFunction to DOFVector
template <class Coeff, class GB, class TP> template <class C, class GB, class TP, class R>
template <class Expr, class Tag> template <class Expr, class Tag>
void DiscreteFunction<Coeff,GB,TP>:: void DiscreteFunction<C,GB,TP,R>::
interpolate(Expr&& expr, Tag strategy) interpolate(Expr&& expr, Tag strategy)
{ {
// create temporary copy of data // create temporary copy of data
Coeff tmp(coefficients()); Coefficients tmp(coefficients());
Self tmpView{tmp, this->basis(), this->treePath()}; Self tmpView{tmp, this->basis(), this->treePath()};
tmpView.interpolate_noalias(FWD(expr), strategy); tmpView.interpolate_noalias(FWD(expr), strategy);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include <amdis/common/DerivativeTraits.hpp> #include <amdis/common/DerivativeTraits.hpp>
#include <amdis/common/FieldMatVec.hpp> #include <amdis/common/FieldMatVec.hpp>
#include <amdis/common/Math.hpp> #include <amdis/common/Math.hpp>
#include <amdis/common/RecursiveForEach.hpp>
#include <amdis/functions/HierarchicNodeToRangeMap.hpp>
#include <amdis/functions/NodeIndices.hpp> #include <amdis/functions/NodeIndices.hpp>
#include <amdis/functions/Order.hpp> #include <amdis/functions/Order.hpp>
#include <amdis/typetree/FiniteElementType.hpp> #include <amdis/typetree/FiniteElementType.hpp>
...@@ -14,7 +16,7 @@ ...@@ -14,7 +16,7 @@
namespace AMDiS { namespace AMDiS {
namespace Impl { namespace Impl {
// specialization of Coeff has gather method // specialization for containers with gather method
template <class Coeff, class LocalView, class LocalCoeff, template <class Coeff, class LocalView, class LocalCoeff,
class = decltype(std::declval<Coeff>().gather(std::declval<LocalView>(), std::declval<LocalCoeff&>()))> class = decltype(std::declval<Coeff>().gather(std::declval<LocalView>(), std::declval<LocalCoeff&>()))>
void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoeff, Dune::PriorityTag<2>) void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoeff, Dune::PriorityTag<2>)
...@@ -22,8 +24,9 @@ void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoe ...@@ -22,8 +24,9 @@ void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoe
coeff.gather(localView, localCoeff); coeff.gather(localView, localCoeff);
} }
// fallback implementation // implementation for containers with multi-index access
template <class Coeff, class LocalView, class LocalCoeff> template <class Coeff, class LocalView, class LocalCoeff,
class = decltype(std::declval<Coeff>()[std::declval<typename LocalView::MultiIndex>()])>
void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoeff, Dune::PriorityTag<1>) void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoeff, Dune::PriorityTag<1>)
{ {
localCoeff.resize(localView.size()); localCoeff.resize(localView.size());
...@@ -32,12 +35,24 @@ void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoe ...@@ -32,12 +35,24 @@ void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoe
*it++ = coeff[idx]; *it++ = coeff[idx];
} }
// fallback implementation
template <class Coeff, class LocalView, class LocalCoeff,
class = decltype(std::declval<Coeff>()[std::integral_constant<std::size_t,0>{}])>
void gather(Coeff const& coeff, LocalView const& localView, LocalCoeff& localCoeff, Dune::PriorityTag<0>)
{
auto backend = Dune::Functions::istlVectorBackend(coeff);
localCoeff.resize(localView.size());
auto it = localCoeff.begin();
for (auto const& idx : nodeIndices(localView))
*it++ = backend[idx];
}
} // end namespace Impl } // end namespace Impl
template <class Coeff, class GB, class TP> template <class C, class GB, class TP, class R>
template <class Type> template <class Type>
class DiscreteFunction<Coeff const,GB,TP>::LocalFunction class DiscreteFunction<C const,GB,TP,R>::LocalFunction
{ {
using DomainType = typename DiscreteFunction::Domain; using DomainType = typename DiscreteFunction::Domain;
using RangeType = typename DiscreteFunction::Range; using RangeType = typename DiscreteFunction::Range;
...@@ -55,17 +70,16 @@ private: ...@@ -55,17 +70,16 @@ private:
using LocalView = typename GlobalBasis::LocalView; using LocalView = typename GlobalBasis::LocalView;
using Element = typename EntitySet::Element; using Element = typename EntitySet::Element;
using Geometry = typename Element::Geometry; using Geometry = typename Element::Geometry;
using NodeToRangeMap = Dune::Functions::DefaultNodeToRangeMap<SubTree>; using NodeToRangeMap = HierarchicNodeToRangeMap;
public: public:
/// Constructor. Stores a copy of the DiscreteFunction. /// Constructor. Stores a copy of the DiscreteFunction.
template <class LV> template <class LV>
LocalFunction(std::shared_ptr<LV> localView, TP const& treePath, Coeff const& coefficients, Type type) LocalFunction(std::shared_ptr<LV> localView, TP const& treePath, C const& coefficients, Type type)
: localView_(std::move(localView)) : localView_(std::move(localView))
, treePath_(treePath) , treePath_(treePath)
, coefficients_(coefficients) , coefficients_(coefficients)
, type_(type) , type_(type)
, nodeToRangeMap_(subTree())
{} {}
/// \brief Bind the LocalView to the element /// \brief Bind the LocalView to the element
...@@ -103,7 +117,7 @@ public: ...@@ -103,7 +117,7 @@ public:
return evaluateDivergence(local); return evaluateDivergence(local);
} }
return Range(0); return Range{};
} }
/// \brief Create a LocalFunction representing the derivative. /// \brief Create a LocalFunction representing the derivative.
...@@ -119,7 +133,7 @@ public: ...@@ -119,7 +133,7 @@ public:
-> decltype(AMDiS::order(std::declval<SubTree>())) -> decltype(AMDiS::order(std::declval<SubTree>()))
{ {
assert(bound_); assert(bound_);
return AMDiS::order(subTreeCache()); return AMDiS::order(subTree());
} }