dune-pdelab 2.10-git
Loading...
Searching...
No Matches
iteratorsplit.hh
Go to the documentation of this file.
1#ifndef DUNE_PDELAB_COMMON_PARTITION_ITERATORSPLIT_HH
2#define DUNE_PDELAB_COMMON_PARTITION_ITERATORSPLIT_HH
3
7
9#include <dune/grid/concepts/gridview.hh>
10
12
13#include <vector>
14#include <memory>
15#include <array>
16#include <algorithm>
17
19
20namespace Impl {
21
29template<Dune::Concept::GridView ES>
30class IteratorSplitMixin {
31public:
33 using EntitySet = ES;
35 using Element = typename EntitySet::template Codim<0>::Entity;
37 using PatchSet = IteratorRange<typename EntitySet::template Codim<0>::Iterator>;
39 using LabelSet = std::vector<PatchSet>;
41 using PartitionSet = std::array<LabelSet,1>;
42
49 explicit IteratorSplitMixin(const EntitySet& entity_set, std::size_t patches)
50 : _entity_set{entity_set}
51 , _patches{patches}
52 {
53 update(entity_set);
54 }
55
57 [[nodiscard]] auto entitySet() const noexcept { return _entity_set; }
58
60 [[nodiscard]] auto begin() const {
61 return _partition_set->begin();
62 }
63
65 [[nodiscard]] auto end() const {
66 return _partition_set->end();
67 }
68
69protected:
75 void update(EntitySet entity_set) {
76 _entity_set = entity_set;
77
78 if (_patches == 0) {
79 std::size_t entities_per_patch = 100;
80 switch(EntitySet::dimension) {
81 case 1: entities_per_patch = 125; break;
82 case 2: entities_per_patch = 250; break;
83 default: entities_per_patch = 500; break;
84 }
85 _patches = std::max<std::size_t>(1, entity_set.size(0) / entities_per_patch);
86 }
87
88 PartitionSet partition_set;
89 partition_set[0].clear();
90 partition_set[0].reserve(_patches);
91
92 auto begin_it = _entity_set.template begin<0>();
93 auto end_it = _entity_set.template end<0>();
94 auto dist = std::distance(begin_it, end_it);
95 auto chunk = dist / _patches;
96 auto remainder = dist % _patches;
97
98 for (size_t i = 0; i < _patches-1; ++i) {
99 auto next_end = std::next(begin_it, chunk + (remainder ? 1 : 0));
100 partition_set[0].emplace_back(begin_it, next_end);
101
102 begin_it = next_end;
103 if (remainder) remainder -= 1;
104 }
105
106 // last chunk
107 partition_set[0].emplace_back(begin_it, end_it);
108 _partition_set = std::make_shared<PartitionSet>(std::move(partition_set));
109 }
110
111private:
112 std::shared_ptr<PartitionSet> _partition_set;
113 EntitySet _entity_set;
114 std::size_t _patches;
115};
116
117} // namespace Impl
118
127template<Dune::Concept::GridView EntitySet>
129 : public Impl::IteratorSplitMixin<EntitySet>
130 , public Impl::UncoloredHaloMixin<EntitySet>
131{
132
140 explicit IteratorSplit(const EntitySet& entity_set, std::size_t patches = 0, std::size_t halo_distance = all_interior_halo_region)
141 : Impl::IteratorSplitMixin<EntitySet>{entity_set, patches}
142 , Impl::UncoloredHaloMixin<EntitySet>::UncoloredHaloMixin{halo_distance}
143 {
144 Impl::UncoloredHaloMixin<EntitySet>::updateHalo(*this);
145 }
146
148 void update(const EntitySet& entity_set) {
149 Impl::IteratorSplitMixin<EntitySet>::update(entity_set);
150 Impl::UncoloredHaloMixin<EntitySet>::updateHalo(*this);
151 }
152};
153
162template<Dune::Concept::GridView EntitySet>
164 : public Impl::ColoredHaloAdaptor<Impl::IteratorSplitMixin<EntitySet>>
165{
173 explicit IteratorSplitColored(const EntitySet& entity_set, std::size_t patches = 0, std::size_t halo_distance = all_interior_halo_region)
174 : Impl::ColoredHaloAdaptor<Impl::IteratorSplitMixin<EntitySet>>{Impl::IteratorSplitMixin<EntitySet>{entity_set, patches}, halo_distance}
175 , _patches{patches}
176 {}
177
179 void update(const EntitySet& entity_set) {
180 Impl::IteratorSplitMixin<EntitySet> base(entity_set, _patches);
181 Impl::ColoredHaloAdaptor<Impl::IteratorSplitMixin<EntitySet>>::update(std::move(base));
182 }
183
184private:
185 std::size_t _patches;
186};
187
188} // namespace Dune::PDELab::EntitySetPartition
189
190#endif // DUNE_PDELAB_COMMON_PARTITION_ITERATORSPLIT_HH
Hierarchy< Domain, A >::Iterator update
Definition colored.hh:16
static constexpr std::size_t all_interior_halo_region
Constant for a halo distance with all halo regions being in the interior.
Definition region.hh:21
ALBERTA EL Element
Partition set with entities evenly split on several patches.
Definition iteratorsplit.hh:131
IteratorSplit(const EntitySet &entity_set, std::size_t patches=0, std::size_t halo_distance=all_interior_halo_region)
Construct a IteratorSplit uncolored entity set partition.
Definition iteratorsplit.hh:140
void update(const EntitySet &entity_set)
Update the partition with a new entity set.
Definition iteratorsplit.hh:148
Colored partition set with entities evenly split on several patches.
Definition iteratorsplit.hh:165
IteratorSplitColored(const EntitySet &entity_set, std::size_t patches=0, std::size_t halo_distance=all_interior_halo_region)
Construct a IteratorSplit colored entity set partition.
Definition iteratorsplit.hh:173
void update(const EntitySet &entity_set)
Update the partition with a new entity set.
Definition iteratorsplit.hh:179
T begin(T... args)
T distance(T... args)
T end(T... args)
T next(T... args)
T remainder(T... args)