Skip to content
Snippets Groups Projects
multiindexset.hh 3.23 KiB
Newer Older
// -*- 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::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::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