opm-grid
SubGridPart.hpp
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 // Note: this file is based on defaultgridview.hh from Dune, and is therefore
5 // licensed under the Dune license (GPLv2 + runtime exception),
6 // see https://dune-project.org/about/license/
7 // rather than the OPM license (GPLv3+)
8 // Copyright 2021 Dune contributors.
9 // Copyright 2021 SINTEF Digital, Mathematics and Cybernetics.
10 
11 #ifndef OPM_SUBGRIDPART_HEADER
12 #define OPM_SUBGRIDPART_HEADER
13 
14 #include <dune/common/exceptions.hh>
15 #include <dune/common/typetraits.hh>
16 
17 #include <dune/grid/common/capabilities.hh>
18 #include <dune/grid/common/gridview.hh>
19 
20 #include <algorithm>
21 #include <cassert>
22 #include <cstddef>
23 #include <map>
24 #include <stdexcept>
25 #include <type_traits>
26 #include <unordered_map>
27 #include <unordered_set>
28 #include <vector>
29 
30 namespace Dune
31 {
32 
33 template <class GridImp>
35 
36 template <class GridImp>
39 
41  using Grid = typename std::remove_const<GridImp>::type;
42 
44  using IndexSet = typename Grid ::Traits ::LeafIndexSet;
45 
47  using Intersection = typename Grid ::Traits ::LeafIntersection;
48 
50  using IntersectionIterator = typename Grid ::Traits ::LeafIntersectionIterator;
51 
53  using CollectiveCommunication = typename Grid ::Traits ::Communication;
54 
55 
56  template <class BaseEntityType>
57  class SubEntity : public BaseEntityType
58  {
59  public:
60  SubEntity()
61  : BaseEntityType()
62  , is_owned_(false)
63  {
64  }
65  SubEntity(const BaseEntityType& base, const bool owned)
66  : BaseEntityType(base)
67  , is_owned_(owned)
68  {
69  }
70  auto partitionType() const
71  {
72  if (is_owned_) {
73  return Dune::InteriorEntity;
74  } else {
75  return Dune::OverlapEntity;
76  }
77  }
78  private:
79  bool is_owned_;
80  };
81 
82  template <int cd>
83  struct Codim {
84  using BaseEntity = typename Grid ::Traits ::template Codim<cd>::Entity;
86  using EntitySeed = typename Grid ::Traits ::template Codim<cd>::EntitySeed;
87 
88  using Geometry = typename Grid ::template Codim<cd>::Geometry;
89  using LocalGeometry = typename Grid ::template Codim<cd>::LocalGeometry;
90 
92  template <PartitionIteratorType pit>
93  struct Partition {
96  };
97  };
98 
99  enum { conforming = Capabilities ::isLeafwiseConforming<Grid>::v };
100 };
101 
102 
113 template <class GridImp>
114 class SubGridPart
115 {
116  using ThisType = SubGridPart<GridImp>;
117 
118 public:
119  using Traits = SubGridPartTraits<GridImp>;
120 
122  using Grid = typename Traits::Grid;
123 
125  using IndexSet = typename Traits ::IndexSet;
126 
129 
132 
135 
136 
138  template <int cd>
139  struct Codim : public Traits ::template Codim<cd> {
140  using Entity = typename Traits::template Codim<cd>::Entity;
142  {
143  public:
144  SubIterator(const SubGridPart& view, std::size_t index)
145  : view_(&view)
146  , index_(index)
147  {
148  }
149  const Entity& operator*() const
150  {
151  entity_ = this->view_->get(index_);
152  return entity_;
153  }
154  const Entity* operator->() const
155  {
156  entity_ = this->view_->get(index_);
157  return &entity_;
158  }
159  SubIterator operator++()
160  {
161  ++index_;
162  return *this;
163  }
164  SubIterator operator++(int)
165  {
166  Iterator copy(*this);
167  ++index_;
168  return copy;
169  }
170  bool operator==(const SubIterator& other) const
171  {
172  assert(view_ == other.view_);
173  return index_ == other.index_;
174  }
175  bool operator!=(const SubIterator& other) const
176  {
177  assert(view_ == other.view_);
178  return index_ != other.index_;
179  }
180  private:
181  const SubGridPart* view_;
182  std::size_t index_;
183  mutable Entity entity_; // This may be low-performing for grids with large Entity objects.
184  };
185  using Iterator = SubIterator;
186 
188  template <PartitionIteratorType pit>
189  struct Partition {
192  };
193 
194  };
195 
196  enum { conforming = Traits::conforming };
197  enum { dimension = GridImp::dimension };
198 
199 public:
200 
205  std::vector<typename Codim<0>::Entity::EntitySeed>&& seeds,
206  const bool overlap = true)
207  : grid_(&grid)
208  , subset_(std::move(seeds))
209  , num_owned_(subset_.size())
210  {
211  // Nothing more to do if we do not want to have overlap entities.
212  if (!overlap) {
213  return;
214  }
215 
216  // Add neighbouring not-owned entities to subset_
217  using Seed = typename Codim<0>::Entity::EntitySeed;
218  std::unordered_set<int> owned;
219  std::unordered_map<int, Seed> neighbors;
220  const auto& iset = grid_->leafIndexSet();
221  const auto& leaf_view = grid_->leafGridView();
222  for (const auto& seed : subset_) {
223  // Add this entity to the set of owned indices.
224  const auto& entity = grid_->entity(seed);
225  owned.insert(iset.index(entity));
226  // Iterating over all intersections, ...
227  const auto end = leaf_view.iend(entity);
228  for (auto it = leaf_view.ibegin(entity); it != end; ++it) {
229  if (it->boundary()) {
230  continue;
231  }
232  if (it->neighbor()) {
233  const auto outside_entity = it->outside();
234  // ...for all neighbour entities, add to neighbors.
235  neighbors.try_emplace(iset.index(outside_entity), outside_entity.seed());
236  }
237  }
238  }
239  // Now that owned is complete, we can eliminate any owned entries.
240  std::map<int, Seed> unowned_neighbors;
241  for (const auto& nb : neighbors) {
242  if (owned.count(nb.first) == 0) {
243  unowned_neighbors.insert(nb);
244  }
245  }
246  subset_.resize(subset_.size() + unowned_neighbors.size());
247  std::size_t count = num_owned_;
248  for (const auto& neighbor : unowned_neighbors) {
249  subset_[count] = neighbor.second;
250  ++count;
251  }
252  assert(count == subset_.size());
253  }
254 
256  const Grid& grid() const
257  {
258  assert(grid_);
259  return *grid_;
260  }
261 
263  // const IndexSet& indexSet() const // Not implemented
264 
266  int size(int codim) const
267  {
268  if (codim == 0) {
269  return subset_.size();
270  } else {
271  return 0;
272  }
273  }
274 
276  // int size(const GeometryType& type) const // Not implemented
277 
279  template <int cd>
280  typename Codim<cd>::Iterator begin() const
281  {
282  static_assert(cd == 0, "Only codimension 0 iterators for SubGridPart.");
283  using Iterator = typename Codim<cd>::Iterator;
284  return Iterator(*this, 0);
285  }
286 
288  template <int cd>
289  typename Codim<cd>::Iterator end() const
290  {
291  static_assert(cd == 0, "Only codimension 0 iterators for SubGridPart.");
292  using Iterator = typename Codim<cd>::Iterator;
293  return Iterator(*this, subset_.size());
294  }
295 
296  // We support iterating over Interior_Partition, Overlap_Partition and All_Partition
297 
299  template <int cd, PartitionIteratorType pit>
300  typename Codim<cd>::template Partition<pit>::Iterator begin() const
301  {
302  static_assert(cd == 0, "Only codimension 0 iterators for SubGridPart.");
303  static_assert(pit == Interior_Partition || pit == Overlap_Partition || pit == All_Partition);
304  if constexpr (pit == Interior_Partition || pit == All_Partition) {
305  return begin<0>();
306  } else {
307  // Overlap partition starts at index num_owned_.
308  // Note that it may be empty, i.e. begin() == end().
309  return typename Codim<cd>::Iterator(*this, num_owned_);
310  }
311  }
312 
314  template <int cd, PartitionIteratorType pit>
315  typename Codim<cd>::template Partition<pit>::Iterator end() const
316  {
317  static_assert(cd == 0, "Only codimension 0 iterators for SubGridPart.");
318  static_assert(pit == Interior_Partition || pit == Overlap_Partition || pit == All_Partition);
319  if constexpr (pit == Overlap_Partition || pit == All_Partition) {
320  return end<0>();
321  } else {
322  // Interior partition ends before index num_owned_.
323  return typename Codim<cd>::Iterator(*this, num_owned_);
324  }
325  }
326 
328  IntersectionIterator ibegin(const typename Codim<0>::Entity& entity) const
329  {
330  return entity.impl().ileafbegin();
331  }
332 
334  IntersectionIterator iend(const typename Codim<0>::Entity& entity) const
335  {
336  return entity.impl().ileafend();
337  }
338 
341  {
342  return grid().comm();
343  }
344 
346  int overlapSize(int codim) const
347  {
348  if (codim == 0) {
349  return subset_.size() - num_owned_;
350  } else {
351  return 0;
352  }
353  }
354 
356  int ghostSize([[maybe_unused]] int codim) const
357  {
358  return 0;
359  }
360 
362  // template <class DataHandleImp, class DataType>
363  // void
364  // communicate(CommDataHandleIF<DataHandleImp, DataType>& data, InterfaceType iftype, CommunicationDirection dir) const
365  // Not implemented.
366 
367 private:
368  using Entity0 = typename Codim<0>::Entity;
369  Entity0 get(std::size_t ii) const
370  {
371  const bool owned = ii < num_owned_;
372  return Entity0(grid_->entity(subset_[ii]), owned);
373  }
374  const Grid* grid_;
375  std::vector<typename Entity0::EntitySeed> subset_;
376  const std::size_t num_owned_;
377 };
378 
379 } // namespace Dune
380 
381 #endif // OPM_SUBGRIDPART_HEADER
Definition: SubGridPart.hpp:37
typename Traits::Grid Grid
type of the grid
Definition: SubGridPart.hpp:122
typename Grid ::Traits ::LeafIntersection Intersection
type of the intersection
Definition: SubGridPart.hpp:47
Codim Structure.
Definition: SubGridPart.hpp:139
typename std::remove_const< GridImp >::type Grid
type of the grid
Definition: SubGridPart.hpp:41
Codim< cd >::Iterator begin() const
obtain number of entities with a given geometry type
Definition: SubGridPart.hpp:280
typename Grid ::Traits ::LeafIndexSet IndexSet
type of the index set
Definition: SubGridPart.hpp:44
The namespace Dune is the main namespace for all Dune code.
Definition: CartesianIndexMapper.hpp:9
Define types needed to iterate over entities of a given partition type.
Definition: SubGridPart.hpp:93
typename Traits ::IndexSet IndexSet
type of the index set
Definition: SubGridPart.hpp:125
Definition: Intersection.hpp:329
Define types needed to iterate over entities of a given partition type.
Definition: SubGridPart.hpp:189
typename Traits ::CollectiveCommunication CollectiveCommunication
type of the collective communication
Definition: SubGridPart.hpp:134
typename Grid ::Traits ::Communication CollectiveCommunication
type of the collective communication
Definition: SubGridPart.hpp:53
Definition: SubGridPart.hpp:141
A class to represent a part of a grid, similar to a GridView.
Definition: SubGridPart.hpp:34
IntersectionIterator iend(const typename Codim< 0 >::Entity &entity) const
obtain end intersection iterator with respect to this view
Definition: SubGridPart.hpp:334
Codim< cd >::Iterator end() const
obtain end iterator for this view
Definition: SubGridPart.hpp:289
Definition: SubGridPart.hpp:57
typename Traits ::IntersectionIterator IntersectionIterator
type of the intersection iterator
Definition: SubGridPart.hpp:131
const CollectiveCommunication & comm() const
obtain collective communication object
Definition: SubGridPart.hpp:340
int size(int codim) const
obtain the index set
Definition: SubGridPart.hpp:266
typename Traits ::Intersection Intersection
type of the intersection
Definition: SubGridPart.hpp:128
Codim< cd >::template Partition< pit >::Iterator end() const
obtain end iterator for this view
Definition: SubGridPart.hpp:315
Codim< cd >::template Partition< pit >::Iterator begin() const
obtain begin iterator for this view
Definition: SubGridPart.hpp:300
typename Grid ::template Codim< cd >::template Partition< pit >::LeafIterator BaseIterator
iterator over a given codim and partition type
Definition: SubGridPart.hpp:95
int ghostSize([[maybe_unused]] int codim) const
Return size of the ghost region for a given codim on the grid view.
Definition: SubGridPart.hpp:356
typename Grid ::Traits ::LeafIntersectionIterator IntersectionIterator
type of the intersection iterator
Definition: SubGridPart.hpp:50
const Grid & grid() const
obtain a const reference to the underlying hierarchic grid
Definition: SubGridPart.hpp:256
Definition: SubGridPart.hpp:83
SubGridPart(const Grid &grid, std::vector< typename Codim< 0 >::Entity::EntitySeed > &&seeds, const bool overlap=true)
Construct a view of the codim 0 entities that can be constructed from the seeds input.
Definition: SubGridPart.hpp:204
int overlapSize(int codim) const
Return size of the overlap region for a given codim on the grid view.
Definition: SubGridPart.hpp:346
IntersectionIterator ibegin(const typename Codim< 0 >::Entity &entity) const
obtain begin intersection iterator with respect to this view
Definition: SubGridPart.hpp:328