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;
30 using Dune::intersections;
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.
@ 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
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.
Various macros to work with Dune module version numbers.