diff --git a/src/amdis/functions/NodeIndices.hpp b/src/amdis/functions/NodeIndices.hpp new file mode 100644 index 0000000000000000000000000000000000000000..98fd9463770d0b92df26461b1806e76a7fced29e --- /dev/null +++ b/src/amdis/functions/NodeIndices.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include <dune/common/rangeutilities.hh> +#include <dune/functions/functionspacebases/concepts.hh> + +#include <amdis/typetree/MultiIndex.hpp> +#include <amdis/utility/MappedRangeView.hpp> + +namespace AMDiS +{ + /// Returns a range over (flat) DOF indices on a node, given by the localView + template <class LocalView, class Node> + auto nodeIndices(LocalView const& localView, Node const& node) + { + using namespace Dune::Functions; + static_assert(Dune::models<Concept::LocalView<typename LocalView::GlobalBasis>, LocalView>(), ""); + static_assert(Dune::models<Concept::BasisTree<typename LocalView::GridView>, Node>(), ""); + + return mappedRangeView(Dune::range(node.size()), [&](std::size_t j) -> std::size_t { + return flatMultiIndex(localView.index(node.localIndex(j))); + }); + } + + /// Returns a range over (flat) DOF indices on the basis tree, given by the localView + template <class LocalView> + auto nodeIndices(LocalView const& localView) + { + using namespace Dune::Functions; + static_assert(Dune::models<Concept::LocalView<typename LocalView::GlobalBasis>, LocalView>(), ""); + + return mappedRangeView(Dune::range(localView.size()), [&](std::size_t i) -> std::size_t { + return flatMultiIndex(localView.index(i)); + }); + } + + + /// Returns the number of DOF indices on a node, given by the localView + template <class LocalView, class Node> + std::size_t nodeIndexCount(LocalView const& /*localView*/, Node const& node) + { + return node.size(); + } + + /// Returns the number of DOF indices on the basis tree, given by the localView + template <class LocalView> + std::size_t nodeIndexCount(LocalView const& localView) + { + return localView.size(); + } + +} // end namespace AMDiS diff --git a/src/amdis/functions/Nodes.hpp b/src/amdis/functions/Nodes.hpp index 5a247083d66b41fe028d9d0a2c3756c8c3e2ada1..79cea5e77ac0e17c3af9b6ea537e30f877f634e2 100644 --- a/src/amdis/functions/Nodes.hpp +++ b/src/amdis/functions/Nodes.hpp @@ -34,4 +34,16 @@ namespace AMDiS #endif } + // dune version independent creation of node from preBasis + template <class PB, class TP> + auto makeNodeIndexSet(PB const& preBasis, TP const& treePath) + { +#if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7) + return preBasis.indexSet(treePath); +#else + DUNE_UNUSED_PARAMETER(treePath); + return preBasis.makeIndexSet(); +#endif + } + } // end namespace AMDiS diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7e7de14fbbfd00a80a5a2ee1e5196989dfef3b59..f6316ae748f73e6118ec528b2fb23f8c65466635 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -87,6 +87,9 @@ dune_add_test(SOURCES MultiTypeVectorTest.cpp dune_add_test(SOURCES MultiTypeMatrixTest.cpp LINK_LIBRARIES amdis) +dune_add_test(SOURCES NodeIndicesTest.cpp + LINK_LIBRARIES amdis) + dune_add_test(SOURCES OperationsTest.cpp LINK_LIBRARIES amdis) diff --git a/test/NodeIndicesTest.cpp b/test/NodeIndicesTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b180d9416a97ab0d91fef7161739faa97473b13c --- /dev/null +++ b/test/NodeIndicesTest.cpp @@ -0,0 +1,73 @@ +#include <dune/grid/yaspgrid.hh> +#include <dune/functions/functionspacebases/compositebasis.hh> +#include <dune/functions/functionspacebases/powerbasis.hh> +#include <dune/functions/functionspacebases/lagrangebasis.hh> + +#include <amdis/functions/NodeIndices.hpp> +#include "Tests.hpp" + +int main() +{ + using namespace AMDiS; + using namespace Dune::Functions::BasisFactory; + + // create grid + Dune::YaspGrid<2> grid({1.0, 1.0}, {1, 1}); + auto gridView = grid.leafGridView(); + + // create basis + auto taylorHoodBasis = makeBasis( + gridView, + composite( + power<2>(lagrange<2>(), flatInterleaved()), + lagrange<1>(), + flatLexicographic() + )); + + auto localView = taylorHoodBasis.localView(); + + for (auto const& e : elements(gridView)) { + localView.bind(e); + + std::size_t numDofs = 2*(3*3) + (2*2); + std::size_t numNodeIndices = nodeIndexCount(localView); + AMDIS_TEST_EQ(numNodeIndices, numDofs); + + std::size_t num = 0; + for (std::size_t dof : nodeIndices(localView)) { + DUNE_UNUSED_PARAMETER(dof); + num++; + } + AMDIS_TEST_EQ(num, numDofs); + + auto node = localView.tree(); + numNodeIndices = nodeIndexCount(localView, node); + AMDIS_TEST_EQ(numNodeIndices, numDofs); + + // count the number of velocity dofs + std::size_t numVelDofs = 2*(3*3); + auto v_node = Dune::TypeTree::child(node, Dune::Indices::_0); + std::size_t numVelNodeIndices = nodeIndexCount(localView, v_node); + AMDIS_TEST_EQ(numVelNodeIndices, numVelDofs); + num = 0; + for (std::size_t dof : nodeIndices(localView, v_node)) { + DUNE_UNUSED_PARAMETER(dof); + num++; + } + AMDIS_TEST_EQ(num, numVelDofs); + + // count the number of pressure dofs + std::size_t numPDofs = 2*2; + auto p_node = Dune::TypeTree::child(node, Dune::Indices::_1); + std::size_t numPNodeIndices = nodeIndexCount(localView, p_node); + AMDIS_TEST_EQ(numPNodeIndices, numPDofs); + num = 0; + for (std::size_t dof : nodeIndices(localView, p_node)) { + DUNE_UNUSED_PARAMETER(dof); + num++; + } + AMDIS_TEST_EQ(num, numPDofs); + } + + return report_errors(); +}