multiindexset.hh 3.25 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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 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
// -*- 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>
    IndexType index (const typename LeafIndexSet::Traits::template Codim<cc>::Entity& e) const
    {
      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>
    IndexType subIndex (const typename LeafIndexSet::Traits::template Codim<cc>::Entity& e,
                        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