Commit 0689eaae authored by Praetorius, Simon's avatar Praetorius, Simon

Reduce errors and compiletime in tree traversal

parent efebae43
#include(CheckIncludeFileCXX)
include(CheckCXXSourceCompiles) include(CheckCXXSourceCompiles)
#include(CheckCXXSymbolExists)
# fold expressions (a + ...) # fold expressions (a + ...)
check_cxx_source_compiles(" check_cxx_source_compiles("
...@@ -30,4 +28,16 @@ check_cxx_source_compiles(" ...@@ -30,4 +28,16 @@ check_cxx_source_compiles("
return f<1>(); return f<1>();
} }
" AMDIS_HAS_CXX_CONSTEXPR_IF " AMDIS_HAS_CXX_CONSTEXPR_IF
)
check_cxx_source_compiles("
#include <iostream>
#include <tuple>
int main()
{
auto tup = std::make_tuple(0, 'a', 3.14);
for... (auto elem : tup)
std::cout << elem << std::endl;
}
" AMDIS_HAS_EXPANSION_STATEMENTS
) )
\ No newline at end of file
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
/* some detected compiler features may be used in AMDiS */ /* some detected compiler features may be used in AMDiS */
#cmakedefine AMDIS_HAS_CXX_FOLD_EXPRESSIONS 1 #cmakedefine AMDIS_HAS_CXX_FOLD_EXPRESSIONS 1
#cmakedefine AMDIS_HAS_CXX_CONSTEXPR_IF 1 #cmakedefine AMDIS_HAS_CXX_CONSTEXPR_IF 1
#cmakedefine AMDIS_HAS_EXPANSION_STATEMENTS 1
/* end amdis /* end amdis
Everything below here will be overwritten Everything below here will be overwritten
......
...@@ -24,4 +24,4 @@ add_dependencies(examples ...@@ -24,4 +24,4 @@ add_dependencies(examples
stokes1.2d stokes1.2d
stokes3.2d stokes3.2d
navier_stokes.2d navier_stokes.2d
convection_diffusion.2d) convection_diffusion.2d)
\ No newline at end of file
...@@ -146,9 +146,10 @@ namespace AMDiS ...@@ -146,9 +146,10 @@ namespace AMDiS
if (!segment.boundary()) if (!segment.boundary())
continue; continue;
auto index = segment.boundarySegmentIndex(); Dune::Hybrid::ifElse(Dune::Std::is_detected<HasBoundaryId, Segment>{}, [&](auto id) {
Dune::Hybrid::ifElse(Dune::Std::is_detected<HasBoundaryId, Segment>{}, auto index = segment.boundarySegmentIndex();
[&](auto id) { boundaryIds_[index] = id(segment).boundaryId(); }); boundaryIds_[index] = id(segment).boundaryId();
});
} }
} }
} }
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include <amdis/Output.hpp> #include <amdis/Output.hpp>
#include <amdis/common/ConcurrentCache.hpp> #include <amdis/common/ConcurrentCache.hpp>
#include <amdis/typetree/Traversal.hpp>
#include <amdis/typetree/TreeContainer.hpp> #include <amdis/typetree/TreeContainer.hpp>
#include <amdis/typetree/Visitor.hpp>
namespace AMDiS namespace AMDiS
{ {
...@@ -135,7 +135,7 @@ namespace AMDiS ...@@ -135,7 +135,7 @@ namespace AMDiS
auto lv = basis_->localView(); auto lv = basis_->localView();
auto const& idSet = gv.grid().localIdSet(); auto const& idSet = gv.grid().localIdSet();
forEachLeafNode_(lv.tree(), [&](auto const& node, auto const& tp) { for_each_leaf_node(lv.tree(), [&](auto const& node, auto const& tp) {
nodeDataTransfer_[tp].preAdaptInit(lv, coeff, node); nodeDataTransfer_[tp].preAdaptInit(lv, coeff, node);
}); });
...@@ -148,7 +148,7 @@ namespace AMDiS ...@@ -148,7 +148,7 @@ namespace AMDiS
lv.bind(e); lv.bind(e);
auto& treeContainer = it.first->second; auto& treeContainer = it.first->second;
forEachLeafNode_(lv.tree(), [&](auto const& node, auto const& tp) { for_each_leaf_node(lv.tree(), [&](auto const& node, auto const& tp) {
nodeDataTransfer_[tp].cacheLocal(treeContainer[tp]); nodeDataTransfer_[tp].cacheLocal(treeContainer[tp]);
}); });
} }
...@@ -201,7 +201,7 @@ namespace AMDiS ...@@ -201,7 +201,7 @@ namespace AMDiS
}; };
restrictLocalCompleted = true; restrictLocalCompleted = true;
forEachLeafNode_(lv.tree(), [&](auto const& node, auto const& tp) { for_each_leaf_node(lv.tree(), [&](auto const& node, auto const& tp) {
restrictLocalCompleted &= restrictLocalCompleted &=
nodeDataTransfer_[tp].restrictLocal(father, treeContainer[tp], xInChildCached, nodeDataTransfer_[tp].restrictLocal(father, treeContainer[tp], xInChildCached,
childContainer[tp], init); childContainer[tp], init);
...@@ -224,7 +224,7 @@ namespace AMDiS ...@@ -224,7 +224,7 @@ namespace AMDiS
auto gv = basis_->gridView(); auto gv = basis_->gridView();
auto lv = basis_->localView(); auto lv = basis_->localView();
auto const& idSet = gv.grid().localIdSet(); auto const& idSet = gv.grid().localIdSet();
forEachLeafNode_(lv.tree(), [&](auto const& node, auto const& tp) { for_each_leaf_node(lv.tree(), [&](auto const& node, auto const& tp) {
nodeDataTransfer_[tp].postAdaptInit(lv, coeff, node); nodeDataTransfer_[tp].postAdaptInit(lv, coeff, node);
}); });
...@@ -243,7 +243,7 @@ namespace AMDiS ...@@ -243,7 +243,7 @@ namespace AMDiS
if (it != persistentContainer_.end()) { if (it != persistentContainer_.end()) {
lv.bind(e); lv.bind(e);
auto const& treeContainer = it->second; auto const& treeContainer = it->second;
forEachLeafNode_(lv.tree(), [&](auto const& node, auto const& tp) { for_each_leaf_node(lv.tree(), [&](auto const& node, auto const& tp) {
nodeDataTransfer_[tp].copyLocal(treeContainer[tp]); nodeDataTransfer_[tp].copyLocal(treeContainer[tp]);
}); });
finished_[index] = true; finished_[index] = true;
...@@ -275,7 +275,7 @@ namespace AMDiS ...@@ -275,7 +275,7 @@ namespace AMDiS
return fatherGeo.local(childGeo.global(x)); return fatherGeo.local(childGeo.global(x));
}; };
forEachLeafNode_(lv.tree(), [&](auto const& node, auto const& tp) { for_each_leaf_node(lv.tree(), [&](auto const& node, auto const& tp) {
nodeDataTransfer_[tp].prolongLocal(father, treeContainer[tp], xInFather, init); nodeDataTransfer_[tp].prolongLocal(father, treeContainer[tp], xInFather, init);
}); });
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
#include <amdis/BoundaryCondition.hpp> #include <amdis/BoundaryCondition.hpp>
#include <amdis/common/Concepts.hpp> #include <amdis/common/Concepts.hpp>
#include <amdis/typetree/RangeType.hpp> #include <amdis/typetree/RangeType.hpp>
#include <amdis/typetree/Traversal.hpp>
#include <amdis/typetree/TreeData.hpp> #include <amdis/typetree/TreeData.hpp>
#include <amdis/typetree/Visitor.hpp>
namespace AMDiS namespace AMDiS
{ {
......
...@@ -196,7 +196,7 @@ std::vector<D> PeriodicBC<D,MI>:: ...@@ -196,7 +196,7 @@ std::vector<D> PeriodicBC<D,MI>::
coords(Node const& tree, std::vector<std::size_t> const& localIndices) const coords(Node const& tree, std::vector<std::size_t> const& localIndices) const
{ {
std::vector<D> dofCoords(localIndices.size()); std::vector<D> dofCoords(localIndices.size());
AMDiS::forEachLeafNode_(tree, [&](auto const& node, auto const& tp) for_each_leaf_node(tree, [&](auto const& node, auto const& tp)
{ {
std::size_t size = node.finiteElement().size(); std::size_t size = node.finiteElement().size();
auto geometry = node.element().geometry(); auto geometry = node.element().geometry();
......
...@@ -177,7 +177,7 @@ void ProblemStat<Traits>::createMatricesAndVectors() ...@@ -177,7 +177,7 @@ void ProblemStat<Traits>::createMatricesAndVectors()
rhs_ = std::make_shared<SystemVector>(*globalBasis_, NO_OPERATION); rhs_ = std::make_shared<SystemVector>(*globalBasis_, NO_OPERATION);
auto localView = globalBasis_->localView(); auto localView = globalBasis_->localView();
AMDiS::forEachNode_(localView.tree(), [&,this](auto const& node, auto treePath) for_each_node(localView.tree(), [&,this](auto const& node, auto treePath)
{ {
std::string i = to_string(treePath); std::string i = to_string(treePath);
estimates_[i].resize(globalBasis_->gridView().indexSet().size(0)); estimates_[i].resize(globalBasis_->gridView().indexSet().size(0));
...@@ -205,7 +205,7 @@ void ProblemStat<Traits>::createMarker() ...@@ -205,7 +205,7 @@ void ProblemStat<Traits>::createMarker()
{ {
marker_.clear(); marker_.clear();
auto localView = globalBasis_->localView(); auto localView = globalBasis_->localView();
AMDiS::forEachNode_(localView.tree(), [&,this](auto const& node, auto treePath) for_each_node(localView.tree(), [&,this](auto const& node, auto treePath)
{ {
std::string componentName = name_ + "->marker[" + to_string(treePath) + "]"; std::string componentName = name_ + "->marker[" + to_string(treePath) + "]";
...@@ -232,7 +232,7 @@ void ProblemStat<Traits>::createFileWriter() ...@@ -232,7 +232,7 @@ void ProblemStat<Traits>::createFileWriter()
{ {
filewriter_.clear(); filewriter_.clear();
auto localView = globalBasis_->localView(); auto localView = globalBasis_->localView();
forEachNode_(localView.tree(), [&,this](auto const& node, auto treePath) for_each_node(localView.tree(), [&,this](auto const& node, auto treePath)
{ {
std::string componentName = name_ + "->output[" + to_string(treePath) + "]"; std::string componentName = name_ + "->output[" + to_string(treePath) + "]";
...@@ -428,9 +428,9 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as ...@@ -428,9 +428,9 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as
rhs_->init(asmVector); rhs_->init(asmVector);
auto localView = globalBasis_->localView(); auto localView = globalBasis_->localView();
forEachNode_(localView.tree(), [&,this](auto const& rowNode, auto rowTp) { for_each_node(localView.tree(), [&,this](auto const& rowNode, auto rowTp) {
auto rowBasis = Dune::Functions::subspaceBasis(*globalBasis_, rowTp); auto rowBasis = Dune::Functions::subspaceBasis(*globalBasis_, rowTp);
forEachNode_(localView.tree(), [&,this](auto const& colNode, auto colTp) { for_each_node(localView.tree(), [&,this](auto const& colNode, auto colTp) {
auto colBasis = Dune::Functions::subspaceBasis(*globalBasis_, colTp); auto colBasis = Dune::Functions::subspaceBasis(*globalBasis_, colTp);
for (auto bc : dirichletBCs_[rowNode][colNode]) for (auto bc : dirichletBCs_[rowNode][colNode])
bc->init(rowBasis, colBasis); bc->init(rowBasis, colBasis);
...@@ -456,8 +456,8 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as ...@@ -456,8 +456,8 @@ buildAfterAdapt(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool as
systemMatrix_->finish(asmMatrix); systemMatrix_->finish(asmMatrix);
rhs_->finish(asmVector); rhs_->finish(asmVector);
forEachNode_(localView.tree(), [&,this](auto const& rowNode, auto) { for_each_node(localView.tree(), [&,this](auto const& rowNode, auto) {
forEachNode_(localView.tree(), [&,this](auto const& colNode, auto) { for_each_node(localView.tree(), [&,this](auto const& colNode, auto) {
// finish boundary condition // finish boundary condition
for (auto bc : dirichletBCs_[rowNode][colNode]) for (auto bc : dirichletBCs_[rowNode][colNode])
bc->fillBoundaryCondition(*systemMatrix_, *solution_, *rhs_, rowNode, colNode); bc->fillBoundaryCondition(*systemMatrix_, *solution_, *rhs_, rowNode, colNode);
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#include <initializer_list> #include <initializer_list>
#include <amdis/common/Apply.hpp>
#include <amdis/common/Index.hpp> #include <amdis/common/Index.hpp>
#include <amdis/common/Range.hpp> #include <amdis/common/Range.hpp>
...@@ -16,34 +15,52 @@ namespace AMDiS ...@@ -16,34 +15,52 @@ namespace AMDiS
void ignored_evaluation(std::initializer_list<T>&&) { /* do nothing */ } void ignored_evaluation(std::initializer_list<T>&&) { /* do nothing */ }
} }
template <std::size_t... I, class Tuple, class Functor>
constexpr void for_each(std::index_sequence<I...>, Tuple&& tuple, Functor&& f)
{
using std::get;
#if AMDIS_HAS_EXPANSION_STATEMENTS
for... (auto&& t : tuple) { f(FWD(t)); }
#elif AMDIS_HAS_CXX_FOLD_EXPRESSIONS
(f(get<I>(tuple)),...);
#else
Impl_::ignored_evaluation<int>({0, (f(get<I>(tuple)), 0)...});
#endif
}
template <class Tuple, class Functor> template <class Tuple, class Functor>
constexpr void for_each(Tuple&& tuple, Functor&& f) constexpr void for_each(Tuple&& tuple, Functor&& f)
{ {
#if AMDIS_HAS_CXX_FOLD_EXPRESSIONS Tools::for_each(std::make_index_sequence<Size_v<std::remove_reference_t<Tuple>>>{}, FWD(tuple), FWD(f));
Tools::apply([f=std::move(f)](auto&&... t) { (f(FWD(t)),...); }, tuple); }
#else
Tools::apply([f=std::move(f)](auto&&... t) {
Impl_::ignored_evaluation<int>({0, (f(FWD(t)), 0)...}); template <std::size_t I0 = 0, std::size_t... I, class Functor>
}, tuple); constexpr void for_range(std::index_sequence<I...>, Functor&& f)
#endif {
#if AMDIS_HAS_CXX_FOLD_EXPRESSIONS
(f(index_t<I0+I>{}),...);
#else
Impl_::ignored_evaluation<int>({0, (f(index_t<I0+I>{}), 0)...});
#endif
} }
template <std::size_t I0, std::size_t I1, class Functor> template <std::size_t I0, std::size_t I1, class Functor>
constexpr void for_range(index_t<I0> i0, index_t<I1> i1, Functor&& f) constexpr void for_range(index_t<I0> i0, index_t<I1> i1, Functor&& f)
{ {
Tools::for_each(range_t<I0,I1>{}, FWD(f)); Tools::for_range<I0>(std::make_index_sequence<std::size_t(I1-I0)>{}, FWD(f));
} }
template <std::size_t N, class Functor> template <std::size_t N, class Functor>
constexpr void for_range(index_t<N>, Functor&& f) constexpr void for_range(index_t<N>, Functor&& f)
{ {
Tools::for_each(range_t<0,N>{}, FWD(f)); Tools::for_range(std::make_index_sequence<N>{}, FWD(f));
} }
template <std::size_t I0, std::size_t I1, class Functor> template <std::size_t I0, std::size_t I1, class Functor>
constexpr void for_range(Functor&& f) constexpr void for_range(Functor&& f)
{ {
Tools::for_each(range_t<I0,I1>{}, FWD(f)); Tools::for_range<I0>(std::make_index_sequence<std::size_t(I1-I0)>{}, FWD(f));
} }
} // end namespace Tools } // end namespace Tools
......
...@@ -65,6 +65,12 @@ namespace AMDiS ...@@ -65,6 +65,12 @@ namespace AMDiS
template <class T> template <class T>
using owner = T; using owner = T;
/// A functor with no operation
struct NoOp
{
template <class... T>
constexpr void operator()(T&&...) const { /* no nothing */ }
};
/// Create a unique_ptr by copy/move construction /// Create a unique_ptr by copy/move construction
template <class Obj> template <class Obj>
......
...@@ -147,7 +147,7 @@ LocalFunction::operator()(Domain const& x) const ...@@ -147,7 +147,7 @@ LocalFunction::operator()(Domain const& x) const
auto&& coefficients = *globalFunction_.dofVector_; auto&& coefficients = *globalFunction_.dofVector_;
auto&& nodeToRangeEntry = globalFunction_.nodeToRangeEntry_; auto&& nodeToRangeEntry = globalFunction_.nodeToRangeEntry_;
forEachLeafNode_(*subTree_, [&,this](auto const& node, auto const& tp) for_each_leaf_node(*subTree_, [&,this](auto const& node, auto const& tp)
{ {
auto&& fe = node.finiteElement(); auto&& fe = node.finiteElement();
auto&& localBasis = fe.localBasis(); auto&& localBasis = fe.localBasis();
...@@ -193,7 +193,7 @@ GradientLocalFunction::operator()(Domain const& x) const ...@@ -193,7 +193,7 @@ GradientLocalFunction::operator()(Domain const& x) const
auto&& coefficients = *globalFunction_.dofVector_; auto&& coefficients = *globalFunction_.dofVector_;
auto&& nodeToRangeEntry = globalFunction_.nodeToRangeEntry_; auto&& nodeToRangeEntry = globalFunction_.nodeToRangeEntry_;
forEachLeafNode_(*subTree_, [&,this](auto const& node, auto const& tp) for_each_leaf_node(*subTree_, [&,this](auto const& node, auto const& tp)
{ {
// TODO: may DOFVectorView::Range to FieldVector type if necessary // TODO: may DOFVectorView::Range to FieldVector type if necessary
using LocalDerivativeTraits using LocalDerivativeTraits
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <amdis/Assembler.hpp> #include <amdis/Assembler.hpp>
#include <amdis/LocalOperator.hpp> #include <amdis/LocalOperator.hpp>
#include <amdis/typetree/Visitor.hpp> #include <amdis/typetree/Traversal.hpp>
#include <amdis/utility/AssembleOperators.hpp> #include <amdis/utility/AssembleOperators.hpp>
namespace AMDiS { namespace AMDiS {
...@@ -75,8 +75,8 @@ assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView) ...@@ -75,8 +75,8 @@ assemble(RowLocalView const& rowLocalView, ColLocalView const& colLocalView)
auto const& element = rowLocalView.element(); auto const& element = rowLocalView.element();
auto geometry = element.geometry(); auto geometry = element.geometry();
forEachNode_(rowLocalView.tree(), [&](auto const& rowNode, auto) { for_each_node(rowLocalView.tree(), [&](auto const& rowNode, auto) {
forEachNode_(colLocalView.tree(), [&](auto const& colNode, auto) { for_each_node(colLocalView.tree(), [&](auto const& colNode, auto) {
auto& matOp = operators_[rowNode][colNode]; auto& matOp = operators_[rowNode][colNode];
if (matOp) { if (matOp) {
matOp.bind(element, geometry); matOp.bind(element, geometry);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <amdis/Assembler.hpp> #include <amdis/Assembler.hpp>
#include <amdis/LocalOperator.hpp> #include <amdis/LocalOperator.hpp>
#include <amdis/typetree/Visitor.hpp> #include <amdis/typetree/Traversal.hpp>
#include <amdis/utility/AssembleOperators.hpp> #include <amdis/utility/AssembleOperators.hpp>
namespace AMDiS { namespace AMDiS {
...@@ -66,7 +66,7 @@ assemble(LocalView const& localView) ...@@ -66,7 +66,7 @@ assemble(LocalView const& localView)
auto const& element = localView.element(); auto const& element = localView.element();
auto geometry = element.geometry(); auto geometry = element.geometry();
forEachNode_(localView.tree(), [&](auto const& node, auto) { for_each_node(localView.tree(), [&](auto const& node, auto) {
auto& rhsOp = operators_[node]; auto& rhsOp = operators_[node];
if (rhsOp) { if (rhsOp) {
rhsOp.bind(element, geometry); rhsOp.bind(element, geometry);
......
...@@ -7,5 +7,4 @@ install(FILES ...@@ -7,5 +7,4 @@ install(FILES
TreeContainer.hpp TreeContainer.hpp
TreeData.hpp TreeData.hpp
TreePath.hpp TreePath.hpp
Visitor.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/typetree) DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/amdis/typetree)
This diff is collapsed.
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <vector> #include <vector>
#include <dune/typetree/typetree.hh> #include <dune/typetree/typetree.hh>
#include <amdis/typetree/Visitor.hpp> #include <amdis/typetree/Traversal.hpp>
namespace AMDiS namespace AMDiS
{ {
...@@ -195,10 +195,10 @@ namespace AMDiS ...@@ -195,10 +195,10 @@ namespace AMDiS
} }
template <class Func> template <class Func>
void applyImpl(Func&& func, std::true_type) { forEachLeafNode_(basis_->localView().tree(), func); } void applyImpl(Func&& func, std::true_type) { for_each_leaf_node(basis_->localView().tree(), func); }
template <class Func> template <class Func>
void applyImpl(Func&& func, std::false_type) { forEachNode_(basis_->localView().tree(), func); } void applyImpl(Func&& func, std::false_type) { for_each_node(basis_->localView().tree(), func); }
protected: protected:
Basis const* basis_ = nullptr; Basis const* basis_ = nullptr;
...@@ -238,7 +238,7 @@ namespace AMDiS ...@@ -238,7 +238,7 @@ namespace AMDiS
void init(RowBasis const& rowBasis, ColBasis const& colBasis) void init(RowBasis const& rowBasis, ColBasis const& colBasis)
{ {
Super::init(rowBasis); Super::init(rowBasis);
forEachNode_(rowBasis.localView().tree(), [&](auto const& node, auto&&) for_each_node(rowBasis.localView().tree(), [&](auto const& node, auto&&)
{ {
(*this)[node].init(colBasis); (*this)[node].init(colBasis);
}); });
......
#pragma once
#include <dune/typetree/visitor.hh>
#include <amdis/typetree/Traversal.hpp>
namespace AMDiS
{
// from dune-typetree merge-request !2
namespace Impl
{
template <class PreFunc, class LeafFunc, class PostFunc>
class CallbackVisitor
: public Dune::TypeTree::TreeVisitor
{
public:
CallbackVisitor(PreFunc& preFunc, LeafFunc& leafFunc, PostFunc& postFunc)
: preFunc_(preFunc)
, leafFunc_(leafFunc)
, postFunc_(postFunc)
{}
template <typename Node, typename TreePath>
void pre(Node&& node, TreePath treePath)
{
preFunc_(node, treePath);
}
template <typename Node, typename TreePath>
void leaf(Node&& node, TreePath treePath)
{
leafFunc_(node, treePath);
}
template <typename Node, typename TreePath>
void post(Node&& node, TreePath treePath)
{
postFunc_(node, treePath);
}
private:
PreFunc& preFunc_;
LeafFunc& leafFunc_;
PostFunc& postFunc_;
};
template <class PreFunc, class LeafFunc, class PostFunc>
auto callbackVisitor(PreFunc& preFunc, LeafFunc& leafFunc, PostFunc& postFunc)
{
return CallbackVisitor<PreFunc, LeafFunc, PostFunc>(preFunc, leafFunc, postFunc);
}
} // namespace Impl
/**
* \brief Traverse tree and visit each node
*
* All passed callback functions are called with the
* node and corresponding treepath as arguments.
*
* \param tree The tree to traverse
* \param preFunc This function is called for each inner node before visiting its children
* \param leafFunc This function is called for each leaf node
* \param postFunc This function is called for each inner node after visiting its children
*/
template <class Tree, class PreFunc, class LeafFunc, class PostFunc>
void forEachNode_(Tree&& tree, PreFunc&& preFunc, LeafFunc&& leafFunc, PostFunc&& postFunc)
{
traverseTree(tree, Impl::callbackVisitor(preFunc, leafFunc, postFunc));
}
/**
* \brief Traverse tree and visit each node
*
* All passed callback functions are called with the
* node and corresponding treepath as arguments.
*
* \param tree The tree to traverse
* \param innerFunc This function is called for each inner node before visiting its children
* \param leafFunc This function is called for each leaf node
*/
template <class Tree, class InnerFunc, class LeafFunc>
void forEachNode_(Tree&& tree, InnerFunc&& innerFunc, LeafFunc&& leafFunc)
{
auto nop = [](auto&&... args) {};
forEachNode_(tree, innerFunc, leafFunc, nop);
}
/**
* \brief Traverse tree and visit each node
*
* The passed callback function is called with the
* node and corresponding treepath as arguments.
*
* \param tree The tree to traverse
* \param nodeFunc This function is called for each node
*/
template <class Tree, class NodeFunc>
void forEachNode_(Tree&& tree, NodeFunc&& nodeFunc)
{
forEachNode_(tree, nodeFunc, nodeFunc);
}
/**
* \brief Traverse tree and visit each leaf node
*
* The passed callback function is called with the
* node and corresponding treepath as arguments.
*
* \param tree The tree to traverse
* \param leafFunc This function is called for each leaf node
*/
template <class Tree, class LeafFunc>
void forEachLeafNode_(Tree&& tree, LeafFunc&& leafFunc)
{
auto nop = [](auto&&... args) {};
forEachNode_(tree, nop, leafFunc, nop);
}
} // end namespace AMDiS
...@@ -68,7 +68,7 @@ auto makeProblem(typename BasisCreator::GlobalBasis::GridView::Grid& grid, Fcts ...@@ -68,7 +68,7 @@ auto makeProblem(typename BasisCreator::GlobalBasis::GridView::Grid& grid, Fcts
// interpolate given function to initial grid // interpolate given function to initial grid
int k = 0; int k = 0;
AMDiS::forEachLeafNode_(localView.tree(), [&](auto const& node, auto tp) for_each_leaf_node(localView.tree(), [&](auto const& node, auto tp)
{ {
interpolate(globalBasis, tp, prob.solution(tp).coefficients(), funcs[k]); interpolate(globalBasis, tp, prob.solution(tp).coefficients(), funcs[k]);
k++; k++;
...@@ -90,7 +90,7 @@ double calcError(Problem const& prob, Fcts const& funcs) ...@@ -90,7 +90,7 @@ double calcError(Problem const& prob, Fcts const& funcs)
int k = 0; int k = 0;
// interpolate given function onto reference vector // interpolate given function onto reference vector
AMDiS::forEachLeafNode_(localView.tree(), [&](auto const& node, auto tp) for_each_leaf_node(localView.tree(), [&](auto const& node, auto tp)
{ {
interpolate(globalBasis, tp, ref, funcs[k]); interpolate(globalBasis, tp, ref, funcs[k]);
k++; k++;
......
...@@ -25,7 +25,7 @@ bool operator==(TreeData<Basis,NodeData,false> const& t1, TreeData<Basis,NodeDat ...@@ -25,7 +25,7 @@ bool operator==(TreeData<Basis,NodeData,false> const& t1, TreeData<Basis,NodeDat
AMDIS_TEST(t1.basis() == t2.basis() && t1.basis() != nullptr); AMDIS_TEST(t1.basis() == t2.basis() && t1.basis() != nullptr);
bool same = true; bool same = true;
AMDiS::forEachNode_(t1.basis()->localView().tree(), [&](auto const& node, auto) { for_each_node(t1.basis()->localView().tree(), [&](auto const& node, auto) {
same = same && (t1[node] == t2[node]); same = same && (t1[node] == t2[node]);
}); });
...@@ -38,7 +38,7 @@ bool operator==(TreeData<Basis,NodeData,true> const& t1, TreeData<Basis,NodeData ...@@ -38,7 +38,7 @@ bool operator==(TreeData<Basis,NodeData,true> const& t1, TreeData<Basis,NodeData
AMDIS_TEST(t1.basis() == t2.basis() && t1.basis() != nullptr); AMDIS_TEST(t1.basis() == t2.basis() && t1.basis() != nullptr);
bool same = true; bool same = true;
AMDiS::forEachLeafNode_(t1.basis()->localView().tree(), [&](auto const& node, auto) { for_each_leaf_node(t1.basis()->localView().tree(), [&](auto const& node, auto) {
same = same && (t1[node] == t2[node]); same = same && (t1[node] == t2[node]);
}); });
...@@ -73,7 +73,7 @@ int main () ...@@ -73,7 +73,7 @@ int main ()
TreeData<Basis, NodeData, false> treeData; TreeData<Basis, NodeData, false> treeData;
treeData.init(basis); treeData.init(basis);
AMDiS::forEachNode_(tree, [&](auto const& node, auto) { for_each_node(tree, [&](auto const& node, auto) {
treeData[node] = double(node.treeIndex()); treeData[node] = double(node.treeIndex());
}); });