8#include <dune/common/exceptions.hh>
9#include <dune/common/hybridutilities.hh>
10#include <dune/common/version.hh>
11#include <dune/common/typetree/nodeconcepts.hh>
12#include <dune/functions/functionspacebases/nodes.hh>
13#include <dune/functions/functionspacebases/lagrangebasis.hh>
14#include <dune/functions/functionspacebases/lagrangedgbasis.hh>
15#include <dune/grid/common/gridenums.hh>
16#include <dune/localfunctions/common/localkey.hh>
18#include <amdis/Output.hpp>
19#include <amdis/common/Apply.hpp>
20#include <amdis/common/ConceptsBase.hpp>
21#include <amdis/common/ForEach.hpp>
22#include <amdis/common/TupleUtility.hpp>
23#include <amdis/typetree/NodeTags.hpp>
24#include <amdis/utility/Twist.hpp>
30 template <
class PreBasis,
class TP,
31 class NodeTag = AMDiS::NodeTag_t<typename PreBasis::Node>>
39 template <
class EntityIdType>
42 using Super = std::pair<EntityIdType, std::size_t>;
46 : Super(EntityIdType{}, i)
64 friend std::ostream& operator<<(std::ostream& os, GlobalIdType
const&
id)
66 os <<
"(" <<
id.first <<
"," <<
id.second <<
")";
71 template <
class Basis>
73 = GlobalIdType<typename Basis::GridView::Grid::GlobalIdSet::IdType>;
97 template <
class GB,
class = std::
void_t<> >
101 using GlobalBasis = GB;
102 using Tree =
typename GB::LocalView::Tree;
103 using size_type = std::size_t;
106 using Grid =
typename GridView::Grid;
107 using Element =
typename GridView::template Codim<0>::Entity;
108 using EntityIdType =
typename Grid::GlobalIdSet::IdType;
109 using PartitionType = Dune::PartitionType;
113 using TreePath =
typename GlobalBasis::PrefixPath;
119 : tree_(globalBasis.localView().tree())
120 , nodeIdSet_(globalBasis.gridView())
121 , twist_(globalBasis.gridView().grid().globalIdSet())
123 initializeTree(tree_);
132 void bind(Element
const& element)
134 bindTree(tree_, element);
135 nodeIdSet_.
bind(tree_);
136 twist_.
bind(element);
137 data_.resize(
size());
138 nodeIdSet_.
fillIn(twist_, data_.begin());
157 assert( i < data_.size() );
158 return data_[i].first;
172 assert( i < data_.size() );
173 return data_[i].second;
180 using Data = std::pair<IdType, PartitionType>;
181 std::vector<Data> data_;
186 template <
class Basis>
197 template <
class PB,
class TP,
class NodeTag>
202 using Node =
typename PreBasis::Node;
203 using GridView =
typename PreBasis::GridView;
204 using size_type = std::size_t;
206 static_assert(Dune::TypeTree::Concept::LeafTreeNode<Node>,
"Generic NodeIdSet implemented for LeafNodes only. Provide a specialization for your node!");
209 static constexpr int dim = GridView::template Codim<0>::Entity::mydimension;
213 : gridView_(gridView)
221 size_ = node_->finiteElement().size();
223 std::fill(std::begin(sizes_), std::end(sizes_), 0u);
224 for (size_type i = 0; i < size_ ; ++i) {
225 Dune::LocalKey
const& localKey = node_->finiteElement().localCoefficients().localKey(i);
226 sizes_[localKey.codim()]++;
228 auto refElem = Dune::referenceElement<double,GridView::dimension>(node_->element().type());
229 for (size_type c = 0; c <= GridView::dimension ; ++c)
230 sizes_[c] /= refElem.size(c);
246 template <
class Twist,
class It>
249 assert(node_ !=
nullptr);
250 const auto& gridIdSet = gridView_.grid().globalIdSet();
252 for (size_type i = 0; i < size_ ; ++i, ++it) {
253 Dune::LocalKey localKey = node_->finiteElement().localCoefficients().localKey(i);
254 unsigned int s = localKey.subEntity();
255 unsigned int c = localKey.codim();
256 it->first = {gridIdSet.subId(node_->element(), s, c), shift + twist.
get(localKey,sizes_[c])};
258 it->second = Dune::Hybrid::switchCases(std::make_index_sequence<dim+1>{}, c,
259 [&](
auto codim) {
return node_->element().template subEntity<codim>(s).partitionType(); },
261 error_exit(
"Invalid codimension c = {}", c);
262 return Dune::PartitionType{};
271 const Node* node_ =
nullptr;
273 std::array<unsigned int,GridView::dimension+1> sizes_;
278 template <
class PreBasis,
class TP>
282 using Node =
typename PreBasis::Node;
283 using GridView =
typename PreBasis::GridView;
284 using size_type = std::size_t;
287 using SubPreBasis =
typename PreBasis::SubPreBasis;
288 using SubTreePath =
decltype(Dune::TypeTree::push_back(std::declval<TP>(), std::size_t(0)));
300 subIds_.bind(node.child(0));
313 return node_->size();
317 template <
class Twist,
class It>
320 assert(node_ !=
nullptr);
321 for (std::size_t child = 0; child < node_->degree(); ++child)
323 size_type subTreeSize = subIds_.size();
324 it = subIds_.fillIn(twist, it, shift);
325 shift += subTreeSize;
331 SubNodeIdSet subIds_;
332 const Node* node_ =
nullptr;
337 template <
class PreBasis,
class TP>
339 :
public NodeIdSet<PreBasis, TP, AMDiS::DynamicPowerNodeTag>
348 template <
class PreBasis,
class TP>
352 using Node =
typename PreBasis::Node;
353 using GridView =
typename PreBasis::GridView;
354 using size_type = std::size_t;
357 static const std::size_t children = Node::degree();
358 using ChildIndices = std::make_index_sequence<children>;
361 template <std::
size_t I>
362 using SubPreBasis =
typename PreBasis::template SubPreBasis<I>;
364 template <std::
size_t I>
365 using SubTreePath =
decltype(Dune::TypeTree::push_back(std::declval<TP>(), Dune::index_constant<I>{}));
367 template <std::
size_t I>
371 using IdsTuple = IndexMapTuple_t<std::make_index_sequence<children>,
SubNodeIdSet>;
375 : idsTuple_(Ranges::applyIndices<children>([&](
auto... i) {
376 return std::make_tuple(
SubNodeIdSet<VALUE(i)>(gridView)...);
384 Ranges::forIndices<0,children>([&](
auto i) {
385 std::get<VALUE(i)>(idsTuple_).bind(node.child(i));
393 Ranges::forEach(idsTuple_, [](
auto& ids) {
401 return node_->size();
405 template <
class Twist,
class It>
408 assert(node_ !=
nullptr);
409 Ranges::forEach(idsTuple_, [&](
auto const& ids)
411 size_type subTreeSize = ids.size();
412 it = ids.fillIn(twist, it, shift);
413 shift += subTreeSize;
420 const Node* node_ =
nullptr;
424 template <
class GV,
int k,
class TP>
425 class NodeIdSet<Dune::Functions::LagrangeDGPreBasis<GV, k>, TP>
428 using PreBasis = Dune::Functions::LagrangeDGPreBasis<GV, k>;
429 using Node =
typename PreBasis::Node;
430 using GridView =
typename PreBasis::GridView;
431 using size_type = std::size_t;
433 NodeIdSet(GridView
const& gridView)
434 : gridView_(gridView)
438 void bind(
const Node& node)
441 size_ = node_->finiteElement().size();
451 size_type
size()
const
457 template <
class Twist,
class It>
458 It
fillIn(Twist
const& , It it, size_type shift = 0)
const
460 assert(node_ !=
nullptr);
461 const auto& gridIdSet = gridView_.grid().globalIdSet();
462 auto elementId = gridIdSet.id(node_->element());
464 for (size_type i = 0; i < size_; ++i, ++it)
466 it->first = {elementId, shift + i};
467 it->second = node_->element().partitionType();
475 const Node* node_ =
nullptr;
Provide global ids for all DOFs in a global basis.
Definition GlobalIdSet.hpp:99
EntityIdType entityId(size_type i) const
Return the global unique ID of the entity associated to the ith DOF on the currently bound element in...
Definition GlobalIdSet.hpp:163
size_type size() const
The number of DOFs on the current element in the basis tree.
Definition GlobalIdSet.hpp:148
PartitionType partitionType(size_type i) const
Return the partition type of the ith DOF on the currently bound element in the basis tree.
Definition GlobalIdSet.hpp:170
void bind(Element const &element)
Bind the IdSet to a grid element.
Definition GlobalIdSet.hpp:132
IdType id(size_type i) const
Return the global unique ID of the ith DOF on the currently bound element in the basis tree.
Definition GlobalIdSet.hpp:155
void unbind()
unbind from the element
Definition GlobalIdSet.hpp:142
PB PreBasis
Pre-basis providing the implementation details.
Definition GlobalBasis.hpp:53
typename PreBasis::GridView GridView
The grid view that the FE space is defined on.
Definition GlobalBasis.hpp:56
Type of a global IDs used to represent DOFs uniquely.
Definition GlobalIdSet.hpp:41
GlobalIdType & operator++()
Increment the second index only.
Definition GlobalIdSet.hpp:52
size_type size() const
Number of DOFs in this node.
Definition GlobalIdSet.hpp:399
void bind(const Node &node)
Bind the idset to a tree node.
Definition GlobalIdSet.hpp:381
It fillIn(Twist const &twist, It it, size_type shift=0) const
Maps from subtree index set [0..size-1] to a globally unique id in global basis.
Definition GlobalIdSet.hpp:406
void unbind()
Unbind the idset.
Definition GlobalIdSet.hpp:390
Definition GlobalIdSet.hpp:280
size_type size() const
Number of DOFs in this node.
Definition GlobalIdSet.hpp:311
void bind(const Node &node)
Bind the idset to a tree node.
Definition GlobalIdSet.hpp:297
It fillIn(Twist const &twist, It it, size_type shift=0) const
Maps from subtree index set [0..size-1] to a globally unique id in global basis.
Definition GlobalIdSet.hpp:318
void unbind()
Unbind the idset.
Definition GlobalIdSet.hpp:304
size_type size() const
Number of DOFs in this node.
Definition GlobalIdSet.hpp:240
void bind(const Node &node)
Bind the idset to a tree node.
Definition GlobalIdSet.hpp:218
It fillIn(Twist const &twist, It it, size_type shift=0) const
Maps from subtree index set [0..size-1] to a globally unique id in global basis.
Definition GlobalIdSet.hpp:247
void unbind()
Unbind the idset.
Definition GlobalIdSet.hpp:234
void bind(Element const &element)
Bind the twist to a codim-0 element. Calculates the global ids of all the element vertices.
Definition Twist.hpp:29
unsigned int get(Dune::LocalKey const &localKey, unsigned int size) const
Get the permutated local dof index, living on a subEntity of the bound element.
Definition Twist.hpp:48
Definition NodeTags.hpp:12
Definition NodeTags.hpp:10
Definition NodeTags.hpp:11