1#ifndef DUNE_PDELAB_COMMON_PARTITIONVIEWENTITYSET_HH 
    2#define DUNE_PDELAB_COMMON_PARTITIONVIEWENTITYSET_HH 
   13#include <dune/geometry/referenceelements.hh> 
   16#include <dune/grid/common/partitionset.hh> 
   17#include <dune/grid/common/rangegenerators.hh> 
   29    using Dune::descendantElements;
 
   32    template<
typename GV, 
typename P>
 
   33    class PartitionViewEntitySet;
 
   35    template<
typename GV, 
typename P>
 
   36    class PartitionViewEntitySetIndexSet;
 
   38    template<
typename GV, 
typename P>
 
   39    struct PartitionViewEntitySetTraits
 
   42      using Partitions = 
typename std::decay<P>::type;
 
   44      using Grid = 
typename GV::Traits::Grid;
 
   47      using IndexSet = PartitionViewEntitySetIndexSet<GV,Partitions>;
 
   48      using BaseIndexSet = 
typename GV::Traits::IndexSet;
 
   50      using Element = 
typename GV::template Codim<0>::Entity;
 
   52      using Intersection = 
typename GV::Traits::Intersection;
 
   54      using IntersectionIterator = 
typename GV::Traits::IntersectionIterator;
 
   56      using Communication = 
typename GV::Traits::Communication;
 
   58      using size_type = std::size_t;
 
   61      using Index = 
typename BaseIndexSet::IndexType;
 
   63      using Types = std::vector<GeometryType>;
 
   65      using CodimMask = std::bitset<GV::dimension + 1>;
 
   69      constexpr static Index invalidIndex()
 
   71        return ~static_cast<Index>(0ull);
 
   74      static const bool conforming = GV::Traits::conforming;
 
   76      static const dim_type dimension = GV::dimension;
 
   78      static const dim_type dimensionworld = GV::dimensionworld;
 
   80      template<dim_type codim>
 
   84        using Iterator = 
typename GV::template Codim<codim>::template Partition<Partitions::partitionIterator()>::Iterator;
 
   86        using Entity = 
typename GV::template Codim<codim>::Entity;
 
   88        using Geometry = 
typename GV::template Codim<codim>::Geometry;
 
   90        using LocalGeometry = 
typename GV::template Codim<codim>::LocalGeometry;
 
   92        template<PartitionIteratorType pitype>
 
   96          using Iterator = 
typename GV::template Codim<codim>::template Partition<pitype>::Iterator;
 
  117    template<
typename GV, 
typename P>
 
  123      using Traits = PartitionViewEntitySetTraits<GV,P>;
 
  125      using Partitions = 
typename Traits::Partitions;
 
  126      using Grid      = 
typename Traits::Grid;
 
  127      using GridView = 
typename Traits::GridView;
 
  128      using IndexSet  = 
typename Traits::IndexSet;
 
  129      using BaseIndexSet = 
typename Traits::BaseIndexSet;
 
  130      using Element = 
typename Traits::Element;
 
  131      using Intersection = 
typename Traits::Intersection;
 
  132      using IntersectionIterator = 
typename Traits::IntersectionIterator;
 
  133      using Communication = 
typename Traits::Communication;
 
  134      using CodimMask = 
typename Traits::CodimMask;
 
  135      using CoordinateField = 
typename Traits::CoordinateField;
 
  136      using size_type = 
typename Traits::size_type;
 
  137      using dim_type = 
typename Traits::dim_type;
 
  139      using ctype = CoordinateField;
 
  141      static const bool conforming = Traits::conforming;
 
  142      static const dim_type dimension = Traits::dimension;
 
  143      static const dim_type dimensionworld = Traits::dimensionworld;
 
  145      template<dim_type codim>
 
  146      using Codim = 
typename Traits::template Codim<codim>;
 
  148      constexpr static Partitions partitions()
 
  153      constexpr static CodimMask allCodims()
 
  158      const Grid& grid()
 const 
  175      template<dim_type codim>
 
  179        return gridView().template begin<codim,Partitions::partitionIterator()>();
 
  182      template<dim_type codim>
 
  186        return gridView().template end<codim,Partitions::partitionIterator()>();
 
  189      template<dim_type codim, PartitionIteratorType pitype>
 
  190      typename GV::template Codim<codim>::template Partition<pitype>::Iterator
 
  193        return gridView().template begin<codim,pitype>();
 
  196      template<dim_type codim, PartitionIteratorType pitype>
 
  197      typename GV::template Codim<codim>::template Partition<pitype>::Iterator
 
  200        return gridView().template end<codim,pitype>();
 
  203      size_type size(dim_type codim)
 const 
  208      size_type size(
const GeometryType& 
gt)
 const 
  213      template<
typename Entity>
 
  214      bool contains(
const Entity& e)
 const 
  219      bool contains(dim_type codim)
 const 
  224      bool contains(
const GeometryType& 
gt)
 const 
  229      IntersectionIterator ibegin(
const typename Codim<0>::Entity& entity)
 const 
  234      IntersectionIterator iend(
const typename Codim<0>::Entity& entity)
 const 
  239      const Communication& comm()
 const 
  256      template<
typename DataHandle>
 
  259        gridView().communicate(data,iftype,dir);
 
  269        : _index_set(
std::make_shared<
IndexSet>(gv,supported_codims,true))
 
  272      explicit PartitionViewEntitySet(
const GridView& gv, 
bool initialize = 
true)
 
  273        : _index_set(
std::make_shared<
IndexSet>(gv,CodimMask(initialize ? ~0ull : 0ull),initialize))
 
  285        _index_set->addCodim(codim);
 
  291        _index_set->removeCodim(codim);
 
  297        return _index_set->needsUpdate();
 
  311        return _index_set->update(force);
 
  323        return _index_set == other._index_set;
 
  328        return not (*
this == other);
 
  333      std::shared_ptr<IndexSet> _index_set;
 
  337    template<
typename GV, 
typename P>
 
  338    class PartitionViewEntitySetIndexSetBase
 
  341      template<
typename,
typename>
 
  342      friend class PartitionViewEntitySet;
 
  346      using Traits = PartitionViewEntitySetTraits<GV,P>;
 
  348      using Partitions = 
typename Traits::Partitions;
 
  349      using Grid      = 
typename Traits::Grid;
 
  350      using GridView = 
typename Traits::GridView;
 
  351      using BaseIndexSet = 
typename Traits::BaseIndexSet;
 
  352      using size_type = 
typename Traits::size_type;
 
  353      using dim_type = 
typename Traits::dim_type;
 
  354      using Index = 
typename Traits::Index;
 
  355      using Types = 
typename Traits::Types;
 
  356      using CodimMask = 
typename Traits::CodimMask;
 
  358      using IndexType = Index;
 
  360      static const dim_type dimension = Traits::dimension;
 
  362      constexpr static Index invalidIndex()
 
  364        return Traits::invalidIndex();
 
  367      template<dim_type codim>
 
  368      using Codim = 
typename Traits::template Codim<codim>;
 
  370      PartitionViewEntitySetIndexSetBase(
const PartitionViewEntitySetIndexSetBase&) = 
delete;
 
  371      PartitionViewEntitySetIndexSetBase& operator=(
const PartitionViewEntitySetIndexSetBase&) = 
delete;
 
  376      bool update(
bool force)
 
  378        if (!(_needs_update || force))
 
  380        std::fill(_gt_offsets.begin(),_gt_offsets.end(),0);
 
  381        std::fill(_mapped_gt_offsets.begin(),_mapped_gt_offsets.end(),0);
 
  382        _active_geometry_types.reset();
 
  383        _geometry_types.resize(0);
 
  384        for (dim_type codim = 0; codim <= GV::dimension; ++codim)
 
  386            if (!_wanted_codims.test(codim))
 
  388            for (
const auto& 
gt : baseIndexSet().types(codim))
 
  391                _gt_offsets[gt_index + 1] = baseIndexSet().size(
gt);
 
  392                _geometry_types.push_back(
gt);
 
  393                _active_geometry_types.set(gt_index);
 
  396        for (dim_type codim = 0; codim <= GV::dimension; ++codim)
 
  398            auto range = std::equal_range(
 
  399              _geometry_types.begin(),
 
  400              _geometry_types.end(),
 
  402              [](
const GeometryType& x, 
const GeometryType& y)
 
  405                return y.dim() < x.dim();
 
  407            _per_codim_geometry_types[codim] = Types{
range.first,
range.second};
 
  410        std::partial_sum(_gt_offsets.begin(),_gt_offsets.end(),_gt_offsets.begin());
 
  411        _active_codims = _wanted_codims;
 
  412        _needs_update = 
false;
 
  418      size_type 
size(GeometryType 
gt)
 const 
  420        assert(!needsUpdate());
 
  422        return _mapped_gt_offsets[gt_index + 1] - _mapped_gt_offsets[gt_index];
 
  425      size_type 
size(dim_type codim)
 const 
  427        assert(!needsUpdate());
 
  428        auto dim = GV::dimension;
 
  433      template<
typename Entity>
 
  434      bool contains(
const Entity& e)
 const 
  436        return Partitions::contains(e.partitionType()) ? baseIndexSet().contains(e) : 
false;
 
  441        return _active_codims.test(codim);
 
  449      const BaseIndexSet& baseIndexSet()
 const 
  451        return _gv.indexSet();
 
  454      Types types(dim_type codim)
 const 
  456        assert(!needsUpdate());
 
  457        return _per_codim_geometry_types[codim];
 
  462        assert(!needsUpdate());
 
  463        return _geometry_types;
 
  466      PartitionViewEntitySetIndexSetBase(
const GV& gv, CodimMask wanted_codims)
 
  468        , _needs_update(true)
 
  469        , _wanted_codims(wanted_codims)
 
  472      const GridView& gridView()
 const 
  477      bool needsUpdate()
 const 
  479        return _needs_update;
 
  486        _needs_update = 
true;
 
  487        _wanted_codims.reset();
 
  490      void addCodim(dim_type codim)
 
  492        _wanted_codims.set(codim);
 
  493        _needs_update = _wanted_codims != _active_codims || _wanted_codims.none();
 
  496      void removeCodim(dim_type codim)
 
  498        _wanted_codims.reset(codim);
 
  499        _needs_update = _wanted_codims != _active_codims || _wanted_codims.none();
 
  504      CodimMask _wanted_codims;
 
  506      CodimMask _active_codims;
 
  512      std::vector<GeometryType> _geometry_types;
 
  513      std::array<Types,GV::dimension + 1> _per_codim_geometry_types;
 
  517    template<
typename GV, 
typename P>
 
  518    class PartitionViewEntitySetIndexSet
 
  519      : 
public PartitionViewEntitySetIndexSetBase<GV,P>
 
  522      using Base = PartitionViewEntitySetIndexSetBase<GV,P>;
 
  524      template<
typename,
typename>
 
  525      friend class PartitionViewEntitySet;
 
  529      using typename Base::Traits;
 
  530      using typename Base::Index;
 
  531      using typename Base::Partitions;
 
  532      using typename Base::size_type;
 
  533      using typename Base::dim_type;
 
  535      using typename Base::Grid;
 
  537      using Base::gridView;
 
  538      using Base::baseIndexSet;
 
  539      using Base::invalidIndex;
 
  540      using Base::contains;
 
  541      using typename Base::CodimMask;
 
  542      using Base::needsUpdate;
 
  551      template<dim_type dim = 0>
 
  554        return Capabilities::hasEntityIterator<Grid,dim>::v && hasAllEntityIterators(
Dune::Dim<dim+1>{});
 
  557      bool update(
bool force)
 
  559        if (!Base::update(force))
 
  561        _indices.assign(_gt_offsets.back(),invalidIndex());
 
  562        _mapped_gt_offsets[0] = 0;
 
  563        update_codims(std::integral_constant<
bool,hasAllEntityIterators()>{});
 
  564        std::partial_sum(_mapped_gt_offsets.begin(),_mapped_gt_offsets.end(),_mapped_gt_offsets.begin());
 
  568      void update_codims(std::true_type)
 
  576      template<dim_type cd>
 
  579        if (_active_codims.test(codim))
 
  584              if (Partitions::contains(e.partitionType()))
 
  585                _indices[_gt_offsets[gt_index] + baseIndexSet().index(e)] = _mapped_gt_offsets[gt_index + 1]++;
 
  591      void update_codims(std::false_type)
 
  593        std::fill(_indices.begin(),_indices.end(),invalidIndex());
 
  595        auto& index_set = baseIndexSet();
 
  599            if (!Partitions::contains(e.partitionType()))
 
  605                if (!_active_codims.test(codim))
 
  608                size_type sub_entity_count = ref_el.size(codim);
 
  610                for(size_type i = 0; i < sub_entity_count; ++i)
 
  612                    auto gt = ref_el.type(i,codim);
 
  614                    auto index = index_set.subIndex(e,i,codim);
 
  615                    if (_indices[_gt_offsets[gt_index] + index] == invalidIndex())
 
  616                      _indices[_gt_offsets[gt_index] + index] = _mapped_gt_offsets[gt_index + 1]++;
 
  622      template<
class Entity>
 
  623      Index indexImpl(
const Entity& e)
 const 
  625        assert(!needsUpdate());
 
  626        assert(Partitions::contains(e.partitionType()));
 
  629        return _indices[_gt_offsets[gt_index] + baseIndexSet().index(e)];
 
  633      Index subIndexImpl(
const E& e, size_type i, dim_type codim)
 const 
  635        assert(!needsUpdate());
 
  636        assert(Partitions::contains(e.partitionType()));
 
  640        return _indices[_gt_offsets[gt_index] + baseIndexSet().subIndex(e,i,codim)];
 
  646      Index index(
const typename Traits::template Codim<cc>::Entity& e)
 const {
 
  650      template<
class Entity>
 
  651      Index index(
const Entity& e)
 const {
 
  656      Index subIndex(
const typename Traits::template Codim<cc>::Entity& e, size_type i, dim_type codim)
 const {
 
  657        return subIndexImpl(e,i,codim);
 
  662      Index subIndex(
const E& e, size_type i, dim_type codim)
 const {
 
  663        return subIndexImpl(e,i,codim);
 
  667      Index uniqueIndex(
const E& e)
 const 
  669        assert(!needsUpdate());
 
  670        assert(Partitions::contains(e.partitionType()));
 
  673        return _indices[_gt_offsets[gt_index] + baseIndexSet().index(e)] + _mapped_gt_offsets[gt_index];
 
  677      Index uniqueSubIndex(
const E& e, size_type i, dim_type codim)
 const 
  679        assert(!needsUpdate());
 
  680        assert(Partitions::contains(e.partitionType()));
 
  684        return _indices[_gt_offsets[gt_index] + baseIndexSet().subIndex(e,i,codim)] + _mapped_gt_offsets[gt_index];
 
  688      PartitionViewEntitySetIndexSet(
const GV& gv, CodimMask wanted_codims, 
bool initialize)
 
  689        : Base(gv,wanted_codims)
 
  697      using Base::_active_codims;
 
  698      using Base::_gt_offsets;
 
  699      using Base::_mapped_gt_offsets;
 
  701      std::vector<Index> _indices;
 
  705    template<
typename GV>
 
  706    class PartitionViewEntitySetIndexSet<GV,Partitions::
All>
 
  707      : 
public PartitionViewEntitySetIndexSetBase<GV,Partitions::All>
 
  710      using Base = PartitionViewEntitySetIndexSetBase<GV,Dune::Partitions::All>;
 
  712      template<
typename,
typename>
 
  717      using typename Base::Traits;
 
  718      using typename Base::Index;
 
  719      using typename Base::Partitions;
 
  720      using typename Base::size_type;
 
  721      using typename Base::dim_type;
 
  722      using typename Base::CodimMask;
 
  724      using Base::baseIndexSet;
 
  725      using Base::contains;
 
  731        if (!Base::update(force))
 
  733        _mapped_gt_offsets[0] = 0;
 
  734        for (
const auto& 
gt : Base::types())
 
  736        std::partial_sum(_mapped_gt_offsets.begin(),_mapped_gt_offsets.end(),_mapped_gt_offsets.begin());
 
  741      Index subIndexImpl(
const E& e, size_type i, dim_type codim)
 const 
  753      Index index(
const E& e)
 const 
  760      Index index(
const typename Traits::template Codim<cc>::Entity& e)
 const 
  767      Index uniqueIndex(
const E& e)
 const 
  775      Index subIndex(
const typename Traits::template Codim<cc>::Entity& e, size_type i, dim_type codim)
 const {
 
  776        return subIndexImpl(e,i,codim);
 
  780      Index subIndex(
const E& e, size_type i, dim_type codim)
 const {
 
  781        return subIndexImpl(e,i,codim);
 
  785      Index uniqueSubIndex(
const E& e, size_type i, dim_type codim)
 const 
  792      PartitionViewEntitySetIndexSet(
const GV& gv, CodimMask wanted_codims, 
bool initialize = 
true)
 
  793        : Base(gv,wanted_codims)
 
  801      using Base::_mapped_gt_offsets;
 
  805    template<
typename GV>
 
  806    using AllEntitySet = PartitionViewEntitySet<GV,Partitions::All>;
 
  808    template<
typename GV>
 
  809    using OverlappingEntitySet = PartitionViewEntitySet<GV,Partitions::InteriorBorderOverlapFront>;
 
  811    template<
typename GV>
 
  812    using NonOverlappingEntitySet = PartitionViewEntitySet<GV,Partitions::InteriorBorder>;
 
  821        using type = std::false_type;
 
  824      template<
typename GV,
typename P>
 
  825      struct _isEntitySet<PartitionViewEntitySet<GV,P>>
 
  827        using type = std::true_type;
 
  836    using isEntitySet = 
typename impl::_isEntitySet<T>::type;
 
static constexpr std::size_t index(const GeometryType >)
Compute the index for the given geometry type over all dimensions.
Definition: typeindex.hh:138
 
static constexpr std::size_t offset(std::size_t dim)
Compute the starting index for a given dimension including irregular geometry types.
Definition: typeindex.hh:113
 
static constexpr std::size_t size(std::size_t maxdim)
Compute total number of geometry types up to and including the given dimension.
Definition: typeindex.hh:125
 
Grid view abstract base class.
Definition: gridview.hh:66
 
Grid abstract base class.
Definition: grid.hh:375
 
static constexpr int dimension
The dimension of the grid.
Definition: grid.hh:387
 
ct ctype
Define type used for coordinates in grid module.
Definition: grid.hh:518
 
Index Set Interface base class.
Definition: indexidset.hh:78
 
Partition view (or entity set) of a grid view.
Definition: partitionviewentityset.hh:119
 
const IndexSet & indexSet() const
Returns the IndexSet of this EntitySet.
Definition: partitionviewentityset.hh:164
 
void reset()
Reset this EntitySet, which removes all entities from it.
Definition: partitionviewentityset.hh:277
 
bool operator==(const PartitionViewEntitySet &other) const
Compare to another partition view.
Definition: partitionviewentityset.hh:322
 
bool update(bool force=false)
Update the internal state of this EntitySet.
Definition: partitionviewentityset.hh:309
 
const GridView & gridView() const
Returns the underlying GridView.
Definition: partitionviewentityset.hh:263
 
bool operator!=(const PartitionViewEntitySet &other) const
Compare to another partition view.
Definition: partitionviewentityset.hh:327
 
void removeCodim(dim_type codim)
Remove all entities of the given codim from this EntitySet.
Definition: partitionviewentityset.hh:289
 
size_type overlapSize(dim_type codim) const
Returns the overlap size of this EntitySet, which depends on its PartitionSet.
Definition: partitionviewentityset.hh:245
 
const BaseIndexSet & baseIndexSet() const
Returns the IndexSet of the underlying GridView.
Definition: partitionviewentityset.hh:170
 
bool needsUpdate() const
Returns true if you need to call update on this EntitySet before using it.
Definition: partitionviewentityset.hh:295
 
void addCodim(dim_type codim)
Add all entities of the given codim to this EntitySet.
Definition: partitionviewentityset.hh:283
 
size_type ghostSize(dim_type codim) const
Returns the ghost size of this EntitySet, which depends on its PartitionSet.
Definition: partitionviewentityset.hh:251
 
A set of traits classes to store static information about grid implementation.
 
Various macros to work with Dune module version numbers.
 
@ conforming
Output conforming data.
Definition: common.hh:73
 
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
 
static constexpr bool isEntitySet()
Check if F models the GridFunction concept with given signature and entity set.
Definition: functionconcepts.hh:235
 
constexpr GeometryType none(unsigned int dim)
Returns a GeometryType representing a singular of dimension dim.
Definition: type.hh:471
 
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
 
auto elements(const SubDomainGridView< HostGridView > &subDomainGridView)
ADL findable access to element range for a SubDomainGridView.
Definition: subdomain.hh:487
 
auto intersections(const SubDomainGridView< HostGridView > &subDomainGridView, const Element &element)
ADL findable access to intersection range for an element of a SubDomainGridView.
Definition: subdomain.hh:510
 
constexpr Overlap overlap
PartitionSet for the overlap partition.
Definition: partitionset.hh:277
 
PartitionSet<... > All
Type of PartitionSet for all partitions.
Definition: partitionset.hh:267
 
constexpr All all
PartitionSet for all partitions.
Definition: partitionset.hh:295
 
constexpr Ghost ghost
PartitionSet for the ghost partition.
Definition: partitionset.hh:283
 
Dune namespace.
Definition: alignedallocator.hh:13
 
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
 
constexpr std::bool_constant<((II==value)||...)> contains(std::integer_sequence< T, II... >, std::integral_constant< T, value >)
Checks whether or not a given sequence contains a value.
Definition: integersequence.hh:137
 
Static tag representing a codimension.
Definition: dimension.hh:24
 
Static tag representing a dimension.
Definition: dimension.hh:16
 
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:156
 
Helper classes to provide indices for geometrytypes for use in a vector.