version 0.4.1
traversal.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2024 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
9#pragma once
11
12namespace Ikarus::utils {
13
30template <class T, class TreePath, class PowerFunc, class LeafFunc>
31void forEachLeafOrPowerLeafNode(T&& tree, TreePath&& treePath, PowerFunc&& powerFunc, LeafFunc&& leafFunc) {
32 using Tree = std::decay_t<T>;
33 if constexpr (Tree::isLeaf) {
34 leafFunc(tree, treePath);
35 } else if constexpr (Tree::isPower) {
36 if constexpr (Tree::template Child<Dune::Indices::_0>::Type::isLeaf) {
37 powerFunc(tree, treePath);
38 } else {
39 for (std::size_t i = 0; i < tree.degree(); ++i) {
40 auto childTreePath = Dune::TypeTree::push_back(treePath, i);
41 forEachLeafOrPowerLeafNode(tree.child(i), childTreePath, powerFunc, leafFunc);
42 }
43 }
44 } else {
45 auto indices = std::make_index_sequence<Tree::degree()>{};
46 Dune::Hybrid::forEach(indices, [&](auto i) {
47 auto childTreePath = Dune::TypeTree::push_back(treePath, i);
48 forEachLeafOrPowerLeafNode(tree.child(i), childTreePath, powerFunc, leafFunc);
49 });
50 }
51}
52
63template <typename LV, typename F, int size = LV::Element::Geometry::coorddimension>
64requires(std::convertible_to<F, std::function<bool(int, Dune::FieldVector<double, size> &&)>>)
65void forEachLagrangeNodePosition(const LV& localView, F&& f) {
66 static_assert(Concepts::LagrangeNode<std::remove_cvref_t<decltype(localView.tree().child(0))>>,
67 "forEachLagrangeNodePosition is only supported for Lagrange power basis");
68 assert(localView.bound() && "The local view must be bound to an element");
69 const auto& localFE = localView.tree().child(0).finiteElement();
70 std::vector<Dune::FieldVector<double, size>> lagrangeNodeCoords;
71 lagrangeNodeCoords.resize(localFE.size());
72 std::vector<double> out;
73 for (int i = 0; i < size; i++) {
74 auto ithCoord = [&i](const Dune::FieldVector<double, size>& x) { return x[i]; };
75 localFE.localInterpolation().interpolate(ithCoord, out);
76 for (std::size_t j = 0; j < out.size(); j++)
77 lagrangeNodeCoords[j][i] = out[j];
78 }
79 for (int nodeNumber = 0; auto& nCoord : lagrangeNodeCoords)
80 if (f(nodeNumber++, std::move(nCoord)))
81 break;
82}
83} // namespace Ikarus::utils
Several concepts.
Definition: algorithms.hh:17
void forEachLeafOrPowerLeafNode(T &&tree, TreePath &&treePath, PowerFunc &&powerFunc, LeafFunc &&leafFunc)
A function which loops over all the nodes of a tree and performs different actions for a power node (...
Definition: traversal.hh:31
void forEachLagrangeNodePosition(const LV &localView, F &&f)
A helper function that helps in traversing over the local coordinates of an element and call a user-d...
Definition: traversal.hh:65
Definition: utils/dirichletvalues.hh:32
Concept to check if a node in a basis tree is a Lagrangian node.
Definition: concepts.hh:82