multiindexset.hh 3.23 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_MULTI_INDEXSET_HH
#define DUNE_MULTI_INDEXSET_HH

#if ! DUNE_HAVE_CXX_VARIANT
#error "Require C++17 variant!"
#endif

#include <type_traits>
#include <variant>

#include <dune/common/typetraits.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/std/type_traits.hh>

#include <dune/grid/common/indexidset.hh>

namespace Dune
{
  // forward declaration
  template <class HostGrid>
  class MultiGridView;

  template <class HostGrid>
  class MultiIndexSet
  {
  private:
    using LeafIndexSet = typename HostGrid::Traits::LeafIndexSet;
    using LevelIndexSet = typename HostGrid::Traits::LevelIndexSet;
    using IndexSetTypes = std::variant<LeafIndexSet const*, LevelIndexSet const*>;

    friend class MultiGridView<HostGrid>;

  public:
    using IndexType = typename LeafIndexSet::IndexType;
    using Types = typename LeafIndexSet::Types;

    static const int dimension = LeafIndexSet::dimension;

  public:
    template <class IndexSet>
    MultiIndexSet (IndexSet const* indexSet)
      : indexSets_(indexSet)
    {}

    MultiIndexSet (IndexSetTypes const& indexSet)
      : indexSets_(indexSet)
    {}

    /// Map entity to index.
    template <class Entity>
    IndexType index (const Entity& e) const
    {
      return std::visit([&e](auto const* is) { return is->index(e); }, indexSets_);
    }

    /// Map entity to index.
    template <int cc>
60
    IndexType index (const typename LeafIndexSet::template Codim<cc>::Entity& e) const
Praetorius, Simon's avatar
Praetorius, Simon committed
61 62 63 64 65 66 67 68 69 70 71 72 73
    {
      return std::visit([&e](auto const* is) { return is->template index<cc>(e); }, indexSets_);
    }

    /// Map a subentity to an index.
    template <class Entity>
    IndexType subIndex (const Entity& e, int i, unsigned int codim) const
    {
      return std::visit([&e,i,codim](auto const* is) { return is->subIndex(e,i,codim); }, indexSets_);
    }

    /// Map a subentity to an index.
    template <int cc>
74
    IndexType subIndex (const typename LeafIndexSet::template Codim<cc>::Entity& e,
Praetorius, Simon's avatar
Praetorius, Simon committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
                        int i, unsigned int codim) const
    {
      return std::visit([&e,i,codim](auto const* is) { return is->template subIndex<cc>(e,i,codim); }, indexSets_);
    }


    /// Obtain all geometry types of entities in domain
    Types types (int codim) const
    {
      return std::visit([codim](auto const* is) { return is->types(codim); }, indexSets_);
    }

    /// Return total number of entities of given geometry type in entity set \f$E\f$.
    IndexType size (GeometryType type) const
    {
      return std::visit([&type](auto const* is) { return is->size(type); }, indexSets_);
    }

    /// Return total number of entities of given codim in the entity set \f$E\f$. This
    /// is simply a sum over all geometry types.
    IndexType size (int codim) const
    {
      return std::visit([codim](auto const* is) { return is->size(codim); }, indexSets_);
    }

    /// Return true if the given entity is contained in \f$E\f$.
    template <class Entity>
    bool contains (const Entity& e) const
    {
      return std::visit([&e](auto const* is) { return is->contains(e); }, indexSets_);
    }

  private:
    IndexSetTypes indexSets_;
  };

} // end namespace Dune

#endif // DUNE_MULTI_INDEXSET_HH