4#ifndef DUNE_PDELAB_ORDERING_LOCALORDERINGBASE_HH 
    5#define DUNE_PDELAB_ORDERING_LOCALORDERINGBASE_HH 
    7#include <dune/pdelab/ordering/utility.hh> 
    8#include <dune/pdelab/gridfunctionspace/gridfunctionspacebase.hh> 
   28    template<
typename ES, 
typename DI, 
typename CI>
 
   32      friend struct collect_a_priori_fixed_size;
 
   35      friend struct update_fixed_size;
 
   38      friend struct post_collect_used_geometry_types;
 
   41      friend struct post_extract_per_entity_sizes;
 
   43      friend struct pre_collect_used_geometry_types;
 
   46      friend struct collect_used_geometry_types_from_cell;
 
   49      friend struct extract_per_entity_sizes_from_cell;
 
   54      template<
typename size_type>
 
   55      friend struct ::Dune::PDELab::impl::update_ordering_data;
 
   59      static const bool has_dynamic_ordering_children = 
true;
 
   61      static const bool consume_tree_index = 
true;
 
   63      typedef LocalOrderingTraits<ES,DI,CI,MultiIndexOrder::Inner2Outer> Traits;
 
   65      static constexpr auto GT_UNUSED = 
~std::size_t(0);
 
   69      typedef impl::GridFunctionSpaceOrderingData<typename Traits::SizeType> GFSData;
 
   73      void map_local_index(
const typename Traits::SizeType geometry_type_index,
 
   74                           const typename Traits::SizeType entity_index,
 
   75                           typename Traits::TreeIndexView mi,
 
   76                           typename Traits::ContainerIndex& ci)
 const 
   78        if (_child_count == 0) 
 
   80            assert(mi.size() == 1 && 
"MultiIndex length must match GridFunctionSpace tree depth");
 
   81            ci.push_back(mi.back());
 
   85            const typename Traits::SizeType child_index = mi.back();
 
   87              _children[child_index]->map_local_index(geometry_type_index,entity_index,mi.back_popped(),ci);
 
   88            if (_container_blocked)
 
   90                ci.push_back(child_index);
 
   92            else if (child_index > 0)
 
   96                    const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
 
   97                    ci.back() += _gt_dof_offsets[index];
 
  101                    assert(_gt_used[geometry_type_index]);
 
  102                    const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1;
 
  103                    ci.back() += _entity_dof_offsets[index];
 
  121      template<
typename ItIn, 
typename ItOut>
 
  124        if (_child_count == 0) 
 
  126          for (ItIn in = begin; in != end; ++in, ++out) {
 
  127            assert(in->size() == 1 &&
 
  128                   "MultiIndex length must match GridFunctionSpace tree depth");
 
  129            out->push_back(in->treeIndex().back());
 
  131        } 
else if (_container_blocked) 
 
  133          for (ItIn in = begin; in != end; ++in, ++out)
 
  134            out->push_back(in->treeIndex().back());
 
  135        } 
else if (_fixed_size) 
 
  137          for (ItIn in = begin; in != end; ++in, ++out) {
 
  138            const typename Traits::SizeType child_index =
 
  139                in->treeIndex().back();
 
  140            const typename Traits::SizeType gt_index =
 
  141                Traits::DOFIndexAccessor::geometryType(*in);
 
  142            if (child_index > 0) {
 
  143              const typename Traits::SizeType index =
 
  144                  gt_index * _child_count + child_index - 1;
 
  145              out->back() += _gt_dof_offsets[index];
 
  150          for (ItIn in = begin; in != end; ++in, ++out) {
 
  151            const typename Traits::SizeType child_index =
 
  152                in->treeIndex().back();
 
  153            if (child_index > 0) {
 
  154              const typename Traits::SizeType gt_index =
 
  155                  Traits::DOFIndexAccessor::geometryType(*in);
 
  156              const typename Traits::SizeType entity_index =
 
  157                  Traits::DOFIndexAccessor::entityIndex(*in);
 
  159              assert(_gt_used[gt_index]);
 
  161              const typename Traits::SizeType index =
 
  162                  (_gt_entity_offsets[gt_index] + entity_index) *
 
  165              out->back() += _entity_dof_offsets[index];
 
  171      template<
typename CIOutIterator, 
typename DIOutIterator = DummyDOFIndexIterator>
 
  172      typename Traits::SizeType
 
  173      extract_entity_indices(
const typename Traits::DOFIndex::EntityIndex& ei,
 
  174                             typename Traits::SizeType child_index,
 
  175                             CIOutIterator ci_out, 
const CIOutIterator ci_end,
 
  176                             DIOutIterator di_out = DIOutIterator())
 const 
  178        typedef typename Traits::SizeType size_type;
 
  180        const size_type geometry_type_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(ei);
 
  181        const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(ei);
 
  183        if (!_gt_used[geometry_type_index])
 
  186        if (_child_count == 0)
 
  188            const size_type size = _fixed_size
 
  189              ? _gt_dof_offsets[geometry_type_index]
 
  190              : _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index)];
 
  192            for (size_type i = 0; i < size; ++i, ++ci_out, ++di_out)
 
  194                ci_out->push_back(i);
 
  195                di_out->treeIndex().push_back(i);
 
  201            if (_container_blocked)
 
  203                for (; ci_out != ci_end; ++ci_out)
 
  205                    ci_out->push_back(child_index);
 
  208            else if (child_index > 0)
 
  211                  for (; ci_out != ci_end; ++ci_out)
 
  213                      const typename Traits::SizeType index = geometry_type_index * _child_count + child_index - 1;
 
  214                      ci_out->back() += _gt_dof_offsets[index];
 
  217                  for (; ci_out != ci_end; ++ci_out)
 
  219                      const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1;
 
  220                      ci_out->back() += _entity_dof_offsets[index];
 
  229      typename Traits::SizeType size(
const typename Traits::DOFIndex::EntityIndex& index)
 const 
  232          Traits::DOFIndexAccessor::GeometryIndex::geometryType(index),
 
  233          Traits::DOFIndexAccessor::GeometryIndex::entityIndex(index)
 
  237      typename Traits::SizeType size(
const typename Traits::SizeType geometry_type_index, 
const typename Traits::SizeType entity_index)
 const 
  240          return _child_count > 0
 
  241            ? _gt_dof_offsets[geometry_type_index * _child_count + _child_count - 1]
 
  242            : _gt_dof_offsets[geometry_type_index];
 
  244        if (!_gt_used[geometry_type_index])
 
  247        return _child_count > 0
 
  248          ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + _child_count - 1]
 
  249          : _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index)];
 
  252      typename Traits::SizeType size(
const typename Traits::SizeType geometry_type_index, 
const typename Traits::SizeType entity_index, 
const typename Traits::SizeType child_index)
 const 
  254        assert(child_index < _child_count);
 
  257            const typename Traits::SizeType index = geometry_type_index * _child_count + child_index;
 
  258            return child_index > 0 ? _gt_dof_offsets[index] - _gt_dof_offsets[index-1] : _gt_dof_offsets[index];
 
  262            if (_gt_used[geometry_type_index])
 
  264                const typename Traits::SizeType index = (_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index;
 
  265                return child_index > 0 ? _entity_dof_offsets[index] - _entity_dof_offsets[index-1] : _entity_dof_offsets[index];
 
  286      typename Traits::SizeType
 
  287      node_size(
const Node& node, 
typename Traits::ContainerIndex suffix,
 
  288           const typename Traits::DOFIndex::EntityIndex &index)
 const {
 
  289        using size_type = 
typename Traits::size_type;
 
  292        if (suffix.size() == 0)
 
  293          return node.size(index);
 
  295        if constexpr (Node::isLeaf) {
 
  299          auto back_index = suffix.back();
 
  303          if (node.containerBlocked()) {
 
  309            const size_type gt_index = Traits::DOFIndexAccessor::GeometryIndex::geometryType(index);
 
  310            const size_type entity_index = Traits::DOFIndexAccessor::GeometryIndex::entityIndex(index);
 
  311            auto dof_begin = node._fixed_size ? node._gt_dof_offsets.begin() : node._entity_dof_offsets.begin();
 
  312            auto dof_end = node._fixed_size ? node._gt_dof_offsets.end() : node._entity_dof_offsets.end();
 
  313            auto dof_it = std::prev(std::upper_bound(dof_begin, dof_end, back_index));
 
  314            size_type dof_dist = std::distance(dof_begin, dof_it);
 
  315            if (node._fixed_size)
 
  316              _child = dof_dist - gt_index * node._child_count + 1;
 
  318              _child = dof_dist - (node._gt_entity_offsets[gt_index] + entity_index) * node._child_count + 1;
 
  321          assert(node.degree() > _child);
 
  322          if constexpr (Node::isPower) {
 
  323            return node.child(_child).size(suffix, index);
 
  325            typename Traits::SizeType _size;
 
  331                _size = node.child(i).size(suffix, index);
 
  340      typename Traits::SizeType offset(
const typename Traits::SizeType geometry_type_index, 
const typename Traits::SizeType entity_index, 
const typename Traits::SizeType child_index)
 const 
  342        assert(child_index < _child_count);
 
  343        assert(_gt_used[geometry_type_index]);
 
  345          return child_index > 0 ? _gt_dof_offsets[geometry_type_index * _child_count + child_index - 1] : 0;
 
  347          return child_index > 0 ? _entity_dof_offsets[(_gt_entity_offsets[geometry_type_index] + entity_index) * _child_count + child_index - 1] : 0;
 
  350      template<
typename Node>
 
  351      LocalOrderingBase(Node& node, 
bool container_blocked, GFSData* gfs_data)
 
  353        , _fixed_size_possible(false)
 
  354        , _container_blocked(container_blocked)
 
  356        , _child_count(TypeTree::
degree(node))
 
  357        , _children(TypeTree::
degree(node),nullptr)
 
  358        , _gfs_data(gfs_data)
 
  368      bool contains(
const GeometryType& 
gt)
 const 
  373      bool contains_geometry_type(
typename Traits::SizeType gt_index)
 const 
  375        return _gt_used[gt_index];
 
  378      bool contains(
typename Traits::SizeType codim)
 const 
  380        return _codim_used.test(codim);
 
  383      typename Traits::SizeType maxLocalSize()
 const 
  385        return _max_local_size;
 
  390      bool update_gfs_data_size(
typename Traits::SizeType& size, 
typename Traits::SizeType& block_count)
 const 
  397      bool containerBlocked()
 const 
  399        return _container_blocked;
 
  402      std::size_t childOrderingCount()
 const 
  407      LocalOrderingBase& childOrdering(
typename Traits::SizeType i)
 
  409        return *_children[i];
 
  412      const LocalOrderingBase& childOrdering(
typename Traits::SizeType i)
 const 
  414        return *_children[i];
 
  417      void disable_container_blocking()
 
  419        _container_blocked = 
false;
 
  434        _fixed_size_possible = 
true;
 
  435        for (
const auto& 
child : _children)
 
  436          _fixed_size_possible &= 
child->_fixed_size_possible;
 
  442      bool _fixed_size_possible;
 
  443      bool _container_blocked;
 
  444      std::size_t _max_local_size;
 
  446      const std::size_t _child_count;
 
  447      std::vector<LocalOrderingBase*> _children;
 
  449      typename Traits::CodimFlag _codim_used;
 
  450      std::vector<bool> _gt_used;
 
  452      std::vector<typename Traits::SizeType> _gt_entity_offsets;
 
  453      std::vector<typename Traits::SizeType> _gt_dof_offsets;
 
  454      std::vector<typename Traits::SizeType> _entity_dof_offsets;
 
static constexpr std::size_t index(const GeometryType >)
Compute the index for the given geometry type over all dimensions.
Definition: typeindex.hh:138
 
Transforms a local ordering (entity-wise order) into a global ordering.
Definition: gridviewordering.hh:440
 
Entity-wise orderings.
Definition: localorderingbase.hh:30
 
void map_lfs_indices(const ItIn begin, const ItIn end, ItOut out) const
Set last index of container indices.
Definition: localorderingbase.hh:122
 
void setup_fixed_size_possible()
Initial setup of the flag indicating whether a fixed size ordering is possible.
Definition: localorderingbase.hh:432
 
Traits::SizeType node_size(const Node &node, typename Traits::ContainerIndex suffix, const typename Traits::DOFIndex::EntityIndex &index) const
Gives the size for a given entity and suffix.
Definition: localorderingbase.hh:287
 
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
 
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:257
 
std::size_t degree(const Node &node)
Returns the degree of node as run time information.
Definition: nodeinterface.hh:79
 
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
free standing function for setting up a range based for loop over an integer range for (auto i: range...
Definition: rangeutilities.hh:288
 
void applyToTree(Tree &&tree, Visitor &&visitor)
Apply visitor to TypeTree.
Definition: traversal.hh:238
 
Dune namespace.
Definition: alignedallocator.hh:13
 
Utilities for reduction like operations on ranges.
 
std::size_t fixedSize
The number of data items per index if it is fixed, 0 otherwise.
Definition: variablesizecommunicator.hh:264