DUNE PDELab (unstable)

subdomain.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_COMMON_SUBDOMAIN_HH
8#define DUNE_FUNCTIONS_COMMON_SUBDOMAIN_HH
9
10#include <array>
11#include <cstddef>
12#include <limits>
13#include <type_traits>
14#include <utility>
15#include <vector>
16
19#include <dune/common/iteratorrange.hh>
21
22#include <dune/geometry/type.hh>
24
26#include <dune/grid/common/partitionset.hh>
27
28namespace Dune::Functions::Experimental {
29
30 namespace Impl {
31
32 template<class GridView>
33 using GlobalIntersectionIteratorTraits = Dune::DefaultIteratorTraits<
34 std::forward_iterator_tag,
35 decltype(*std::declval<typename GridView::IntersectionIterator>())>;
36
37
38 template<class GV, class ContainsCallback>
39 class GlobalIntersectionIt
40 : public Dune::IteratorFacadeForTraits<GlobalIntersectionIt<GV, ContainsCallback>, GlobalIntersectionIteratorTraits<GV>>
41 {
42 using Facade = Dune::IteratorFacadeForTraits<GlobalIntersectionIt<GV, ContainsCallback>, GlobalIntersectionIteratorTraits<GV>>;
43
44 public:
45
46 using GridView = GV;
47 using Element = typename GridView::template Codim<0>::Entity;
48 using ElementIterator = typename GridView::template Codim<0>::Iterator;
49 using IntersectionIterator = typename GridView::IntersectionIterator;
50
51 class SentinelIterator
52 {};
53
54 GlobalIntersectionIt(const GridView& gridView, const ContainsCallback& contains, ElementIterator elementIt, ElementIterator elementEnd)
55 : gridView_(gridView)
56 , contains_(contains)
57 , elementIt_(std::move(elementIt))
58 , elementEnd_(std::move(elementEnd))
59 {
60 if (elementIt_ != elementEnd_)
61 {
62 element_ = *elementIt_;
63 iIt_ = gridView_.ibegin(element_);
64 iEnd_ = gridView_.iend(element_);
65 if (not contains_(*iIt_))
66 ++(*this);
67 }
68 }
69
70 using reference = typename Facade::reference;
71
72 reference operator*() const
73 {
74 return *iIt_;
75 }
76
77 GlobalIntersectionIt& operator++()
78 {
79 while(true)
80 {
81 ++iIt_;
82 if (iIt_ == iEnd_)
83 {
84 ++elementIt_;
85 if (elementIt_ == elementEnd_)
86 return *this;
87 element_ = *elementIt_;
88 iIt_ = gridView_.ibegin(element_);
89 iIt_ = gridView_.ibegin(element_);
90 iEnd_ = gridView_.iend(element_);
91 }
92 if (contains_(*iIt_))
93 return *this;
94 }
95 return *this;
96 }
97
98 friend bool operator==(const GlobalIntersectionIt& it1, const GlobalIntersectionIt& it2)
99 {
100 if (it1.elementIt_ != it2.elementIt_)
101 return false;
102 if (it1.elementIt_ == it1.elementEnd_)
103 return true;
104 return (it1.iIt_ == it2.iIt_);
105 }
106
107 friend bool operator==(const GlobalIntersectionIt& it1, const SentinelIterator& it2)
108 {
109 return it1.elementIt_ == it1.elementEnd_;
110 }
111
112 private:
113 GridView gridView_;
114 ContainsCallback contains_;
115 ElementIterator elementIt_;
116 ElementIterator elementEnd_;
117 Element element_;
118 IntersectionIterator iIt_;
119 IntersectionIterator iEnd_;
120 };
121
122 }
123
124
125
146 template<class HGV>
148 {
149 using HostGridView = HGV;
150
151 public:
152
153 using Grid = typename HostGridView::Grid;
154 using Types = std::vector<Dune::GeometryType>;
155 using IndexType = std::size_t;
156
158 template<int codim>
159 struct Codim
160 {
161 using Entity = typename Grid::template Codim<codim>::Entity;
162 using EntitySeed = typename Grid::template Codim<codim>::EntitySeed;
163 using Geometry = typename Grid::template Codim<codim>::Geometry;
164 using LocalGeometry = typename Grid::template Codim<codim>::LocalGeometry;
165 };
166
167 enum {dimension = Grid::dimension};
168
169 private:
170
172
173 static auto allCodimLayout()
174 {
175 return [](Dune::GeometryType, int) { return true; };
176 }
177
178 static constexpr auto typeIndexSize = Dune::GlobalGeometryTypeIndex::size(dimension);
179 static constexpr auto unusesIndex = std::numeric_limits<IndexType>::max();
180
181 public:
182
184 SubDomainIndexSet(const HostGridView& hostGridView)
185 : hostGridView_(hostGridView)
186 , allEntityMapper_(hostGridView_, allCodimLayout())
187 {
188 clear();
189 }
190
191 // *********************************
192 // IndexSet interface methods
193 // *********************************
194
195 IndexType size(Dune::GeometryType gt) const
196 {
197 return sizePerGT_[Dune::GlobalGeometryTypeIndex::index(gt)];
198 }
199
200 IndexType size(int codim) const
201 {
202 return sizePerCodim_[codim];
203 }
204
205 template<class Entity>
206 IndexType index(const Entity& entity) const
207 {
208 auto index = indices_[allEntityMapper_.index(entity)];
209 if (index==unusesIndex)
210 DUNE_THROW(Dune::InvalidStateException, "Accessing nonexisting entry using SubDomainIndexSet::index()!");
211 return index;
212 }
213
214 template<int cc>
215 IndexType index(const typename Codim<cc>::Entity& entity) const
216 {
217 return index<typename Codim<cc>::Entity>(entity);
218 }
219
220 template<class Entity>
221 IndexType subIndex(const Entity& entity, int subEntity, unsigned int codim) const
222 {
223 auto index = indices_[allEntityMapper_.subIndex(entity, subEntity, codim)];
224 if (index==unusesIndex)
225 DUNE_THROW(Dune::InvalidStateException, "Accessing nonexisting entry using SubDomainIndexSet::subIndex()!");
226 return index;
227 }
228
229 template<int cc>
230 IndexType subIndex(const typename Codim<cc>::Entity& entity, int subEntity, unsigned int codim) const
231 {
232 return subIndex<typename Codim<cc>::Entity>(entity, subEntity, codim);
233 }
234
235 template<class Entity >
236 bool contains(const Entity& entity) const
237 {
238 return (indices_[allEntityMapper_.index(entity)] != unusesIndex);
239 }
240
241 Types types(int codim) const
242 {
243 return typesPerCodim_[codim];
244 }
245
246 // *********************************
247 // Extended methods
248 // *********************************
249
251 const HostGridView& hostGridView() const
252 {
253 return hostGridView_;
254 }
255
257 void insertElement(const typename Codim<0>::Entity& element)
258 {
259 const auto& re = referenceElement(element);
260 for (auto codim : Dune::range(0, dimension+1))
261 {
262 for (auto subEntity : Dune::range(re.size(codim)))
263 {
264 auto& index = indices_[allEntityMapper_.subIndex(element, subEntity, codim)];
265 if (index==unusesIndex)
266 {
267 const auto& type = re.type(subEntity, codim);
268 const auto typeIndex = Dune::GlobalGeometryTypeIndex::index(type);
269 index = sizePerGT_[typeIndex];
270 if (sizePerGT_[typeIndex]==0)
271 typesPerCodim_[codim].push_back(type);
272 sizePerGT_[typeIndex]++;
273 sizePerCodim_[codim]++;
274 }
275 }
276 }
277 }
278
279 protected:
280
281 // Clear all data
282 void clear()
283 {
284 for(auto& size : sizePerGT_)
285 size = 0;
286 for(auto& size : sizePerCodim_)
287 size = 0;
288 for(auto& types : typesPerCodim_)
289 types.clear();
290 indices_.clear();
291 indices_.resize(allEntityMapper_.size(), unusesIndex);
292 }
293
294 HostGridView hostGridView_;
295
296 // Global size information
297 std::array<std::size_t, typeIndexSize> sizePerGT_;
298 std::array<std::size_t, dimension+1> sizePerCodim_;
299 std::array<Types, dimension+1> typesPerCodim_;
300
301 AllEntityMapper allEntityMapper_;
302
303 // Index map
304 std::vector<IndexType> indices_;
305 };
306
307
308
321 template<class HGV>
323 {
324
325 template<int codim>
326 class NonImplementedIterator
327 {
328 public:
329 NonImplementedIterator()
330 {
331 static_assert(codim==0, "SubDomainGridView::Codim::Iterator<codim> is only implemented for codim=0");
332 }
333 };
334
335 template<PartitionIteratorType pit>
336 class ElementIterator
337 {
338 using Element = typename HGV::template Codim<0>::Entity;
339 public:
340
341 using HostElementIterator = typename HGV::template Codim<0>::template Partition<pit>::Iterator;
342
343 ElementIterator(const SubDomainIndexSet<HGV>& indexSet, HostElementIterator&& it, HostElementIterator&& endIt)
344 : indexSet_(&indexSet)
345 , hostIt_(std::move(it))
346 , hostEndIt_(std::move(endIt))
347 {
348 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
349 ++hostIt_;
350 }
351
352 ElementIterator& operator++()
353 {
354 ++hostIt_;
355 while ((hostIt_!= hostEndIt_) and (not indexSet_->contains(*hostIt_)))
356 ++hostIt_;
357 return *this;
358 }
359
360 const Element& operator*() const
361 {
362 return *hostIt_;
363 }
364
365 friend bool operator==(const ElementIterator& a, const ElementIterator& b)
366 {
367 return a.hostIt_==b.hostIt_;
368 }
369
370 private:
371 HostElementIterator hostIt_;
372 HostElementIterator hostEndIt_;
373 const SubDomainIndexSet<HGV>* indexSet_;
374 };
375
376 public:
377
378 using HostGridView = HGV;
379
380 using Grid = typename HostGridView::Grid;
381 using ctype = typename Grid::ctype;
383 using Intersection = typename HostGridView::Intersection;
384 using IntersectionIterator = typename HostGridView::IntersectionIterator;
385
387 template<int codim>
388 struct Codim
389 {
390 using Entity = typename Grid::template Codim<codim>::Entity;
391 using EntitySeed = typename Grid::template Codim<codim>::EntitySeed;
392 using Geometry = typename Grid::template Codim<codim>::Geometry;
393 using LocalGeometry = typename Grid::template Codim<codim>::LocalGeometry;
394 using Iterator = std::conditional_t<codim==0, ElementIterator<All_Partition>, NonImplementedIterator<codim>>;
395
396 template<PartitionIteratorType pit>
397 struct Partition
398 {
399 using Iterator = std::conditional_t<codim==0, ElementIterator<pit>, NonImplementedIterator<codim>>;
400 };
401 };
402
403 enum {dimension = Grid::dimension};
404 enum {dimensionworld = Grid::dimensionworld};
405
406 SubDomainGridView(const IndexSet& indexSet)
407 : indexSet_(&indexSet)
408 {}
409
410 SubDomainGridView(const SubDomainGridView& other) = default;
411
412 const Grid& grid() const
413 {
414 return indexSet_->hostGridView().grid();
415 }
416
417 const IndexSet& indexSet() const
418 {
419 return *indexSet_;
420 }
421
422 int size(int codim) const
423 {
424 return indexSet_->size(codim);
425 }
426
427 int size(Dune::GeometryType gt) const
428 {
429 return indexSet_->size(gt);
430 }
431
432 template<class Entity>
433 bool contains(const Entity& entity) const
434 {
435 return indexSet_->contains(entity);
436 }
437
439 template<int codim, PartitionIteratorType pit = All_Partition>
440 typename Codim<codim>::template Partition<pit>::Iterator begin() const
441 {
442 static_assert(codim==0, "SubDomainGridView::begin<codim> is only implemented for codim=0");
443 return {indexSet(), hostGridView().template begin<codim, pit>(), hostGridView().template end<codim, pit>()};
444 }
445
447 template<int codim, PartitionIteratorType pit = All_Partition>
448 typename Codim<codim>::template Partition<pit>::Iterator end() const
449 {
450 static_assert(codim==0, "SubDomainGridView::end<codim> is only implemented for codim=0");
451 return {indexSet(), hostGridView().template end<codim, pit>(), hostGridView().template end<codim, pit>()};
452 }
453
454 decltype(auto) comm() const
455 {
456 return hostGridView().comm();
457 }
458
459 decltype(auto) ibegin(const typename Codim<0>::Entity& element) const
460 {
461 return hostGridView().ibegin(element);
462 }
463
464 decltype(auto) iend(const typename Codim<0>::Entity& element) const
465 {
466 return hostGridView().iend(element);
467 }
468
470 const HostGridView& hostGridView() const
471 {
472 return indexSet_->hostGridView();
473 }
474
475 protected:
476 const IndexSet* indexSet_;
477 };
478
479
480
486 template<class HostGridView>
487 auto elements(const SubDomainGridView<HostGridView>& subDomainGridView)
488 {
489 return Dune::IteratorRange(subDomainGridView.template begin<0>(), subDomainGridView.template end<0>());
490 }
491
497 template<class HostGridView, unsigned int partitions>
499 {
500 constexpr auto pit = partitionSet.partitionIterator();
501 return Dune::IteratorRange(subDomainGridView.template begin<0, pit>(), subDomainGridView.template end<0, pit>());
502 }
503
509 template<class HostGridView, class Element>
510 auto intersections(const SubDomainGridView<HostGridView>& subDomainGridView, const Element& element)
511 {
512 return Dune::IteratorRange(subDomainGridView.ibegin(element), subDomainGridView.iend(element));
513 }
514
515
516
532 template<class HGV>
534 {
535 public:
536
537 using HostGridView = HGV;
538 using Grid = typename HostGridView::Grid;
541
543 template<int codim>
544 struct Codim
545 {
546 using Entity = typename Grid::template Codim<codim>::Entity;
547 using EntitySeed = typename Grid::template Codim<codim>::EntitySeed;
548 using Geometry = typename Grid::template Codim<codim>::Geometry;
549 using LocalGeometry = typename Grid::template Codim<codim>::LocalGeometry;
550 };
551
552 enum {dimension = Grid::dimension};
553
555 SubDomain(const HostGridView& hostGridView)
556 : indexSet_(hostGridView)
557 {}
558
559 const IndexSet& indexSet() const
560 {
561 return indexSet_;
562 }
563
566 {
567 return GridView(indexSet_);
568 }
569
571 HostGridView hostGridView() const
572 {
573 return indexSet_.hostGridView();
574 }
575
577 void insertElement(const typename Codim<0>::Entity& element)
578 {
579 indexSet_.insertElement(element);
580 }
581
583 bool contains(const typename Codim<0>::Entity& element) const
584 {
585 return indexSet_.contains(element);
586 }
587
588 private:
589 IndexSet indexSet_;
590 };
591
592
593
599 template<class SubDomainA, class SubDomainB>
601 {
602 static_assert(
603 std::is_same_v<typename SubDomainA::GridView::Intersection, typename SubDomainB::GridView::Intersection>,
604 "SubDomainInterface requires that both SubDomain types have the same Intersection type");
605
606 public:
607
608 using Intersection = typename SubDomainA::GridView::Intersection;
609
617 SubDomainInterface(const SubDomainA& subDomainA, const SubDomainB& subDomainB)
618 : subDomainA_(subDomainA)
619 , subDomainB_(subDomainB)
620 {}
621
631 bool contains(const Intersection& is) const
632 {
633 if (is.boundary() or not(is.neighbor()))
634 return false;
635 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()))
636 || (subDomainA_.contains(is.outside()) && subDomainB_.contains(is.inside()));
637 }
638
647 bool isOriented(const Intersection& is) const
648 {
649 if (is.boundary() or not(is.neighbor()))
650 return false;
651 return (subDomainA_.contains(is.inside()) && subDomainB_.contains(is.outside()));
652 }
653
660 const auto begin() const
661 {
662 return Impl::GlobalIntersectionIt(subDomainA_.gridView(), [&](const auto& is) {
663 if (is.boundary() or not(is.neighbor()))
664 return false;
665 return subDomainB_.indexSet().contains(is.outside());
666 }, subDomainA_.gridView().template begin<0>(), subDomainA_.gridView().template end<0>());
667 }
668
670 const auto end() const
671 {
672 return typename decltype(begin())::SentinelIterator();
673 }
674
675 private:
676 const SubDomainA& subDomainA_;
677 const SubDomainB& subDomainB_;
678 };
679
680
681
687 template<class SubDomain>
689 {
690 public:
691
692 using Intersection = typename SubDomain::GridView::Intersection;
693
695 SubDomainSkeleton(const SubDomain& subDomain)
696 : subDomain_(subDomain)
697 {}
698
700 bool contains(const Intersection& is) const
701 {
702 if (is.boundary() or not(is.neighbor()))
703 return false;
704 return subDomain_.contains(is.inside()) and subDomain_.contains(is.outside());
705 }
706
707 private:
708 const SubDomain& subDomain_;
709 };
710
711
712
713} // namespace Dune::Functions::Experimental
714
715#endif// DUNE_FUNCTIONS_COMMON_SUBDOMAIN_HH
Wrapper class for entities.
Definition: entity.hh:66
A GridView for a sub-domain.
Definition: subdomain.hh:323
Codim< codim >::template Partition< pit >::Iterator end() const
Create an iterator pointing to the end of the range.
Definition: subdomain.hh:448
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:470
Codim< codim >::template Partition< pit >::Iterator begin() const
Create an iterator pointing to the begin of the range.
Definition: subdomain.hh:440
An IndexSet for a sub-domain.
Definition: subdomain.hh:148
SubDomainIndexSet(const HostGridView &hostGridView)
Construct SubDomainIndexSet for underlying host grid view.
Definition: subdomain.hh:184
void insertElement(const typename Codim< 0 >::Entity &element)
Insert element and all its sub-entities into SubDomainIndexSet.
Definition: subdomain.hh:257
const HostGridView & hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:251
Class representing the intersection between two subdomains.
Definition: subdomain.hh:601
const auto end() const
End iterator (sentinel)
Definition: subdomain.hh:670
bool contains(const Intersection &is) const
Check if intersection is contained in the interface between the subdomains.
Definition: subdomain.hh:631
const auto begin() const
Begin iterator over all intersection between the subdomains.
Definition: subdomain.hh:660
SubDomainInterface(const SubDomainA &subDomainA, const SubDomainB &subDomainB)
Create interface between two subdomains.
Definition: subdomain.hh:617
bool isOriented(const Intersection &is) const
Check if intersection is oriented.
Definition: subdomain.hh:647
Class representing the skeleton of a subdomain.
Definition: subdomain.hh:689
SubDomainSkeleton(const SubDomain &subDomain)
Create skeleton of a subdomain.
Definition: subdomain.hh:695
bool contains(const Intersection &is) const
Check if intersection is contained in the skeleton of the subdomain.
Definition: subdomain.hh:700
Class representing a sub-domain of a GridView.
Definition: subdomain.hh:534
void insertElement(const typename Codim< 0 >::Entity &element)
Insert element and all its sub-entities into SubDomain.
Definition: subdomain.hh:577
GridView gridView() const
Create grid view representing the SubDomain.
Definition: subdomain.hh:565
HostGridView hostGridView() const
Access underlying host grid view.
Definition: subdomain.hh:571
SubDomain(const HostGridView &hostGridView)
Construct SubDomain for underlying host grid view.
Definition: subdomain.hh:555
bool contains(const typename Codim< 0 >::Entity &element) const
Check if element is contained in SubDomain.
Definition: subdomain.hh:583
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
static constexpr std::size_t index(const GeometryType &gt)
Compute the index for the given geometry type over all dimensions.
Definition: typeindex.hh:138
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 abstract base class.
Definition: grid.hh:375
static constexpr int dimension
The dimension of the grid.
Definition: grid.hh:387
static constexpr int dimensionworld
The dimension of the world the grid lives in.
Definition: grid.hh:390
ct ctype
Define type used for coordinates in grid module.
Definition: grid.hh:518
Index Set Interface base class.
Definition: indexidset.hh:78
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:375
CRTP-Mixing class for stl conformant iterators of given iterator category.
Definition: iteratorfacades.hh:1053
constexpr decltype(auto) operator*() const
Dereferencing operator.
Definition: iteratorfacades.hh:1119
constexpr decltype(auto) operator++()
Preincrement operator.
Definition: iteratorfacades.hh:1138
Simple range between a begin and an end iterator.
Definition: iteratorrange.hh:26
size_type size() const
Return total number of entities in the entity set managed by the mapper.
Definition: mcmgmapper.hh:204
Index subIndex(const typename GV::template Codim< 0 >::Entity &e, int i, unsigned int codim) const
Map subentity of codim 0 entity to starting index in array for dof block.
Definition: mcmgmapper.hh:185
Index index(const EntityType &e) const
Map entity to starting index in array for dof block.
Definition: mcmgmapper.hh:171
A few common exception classes.
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
Traits::IntersectionIterator IntersectionIterator
type of the intersection iterator
Definition: gridview.hh:92
unspecified value type referenceElement(T &&... t)
Returns a reference element for the objects t....
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485
constexpr EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
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, Dune::PartitionSet< partitions > partitionSet)
ADL findable access to element range for a SubDomainGridView.
Definition: subdomain.hh:498
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
This file implements iterator facade classes for writing stl conformant iterators.
Mapper for multiple codim and multiple geometry types.
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
STL namespace.
Utilities for reduction like operations on ranges.
Static tag representing a codimension.
Definition: dimension.hh:24
An iterator_traits class providing sensible defaults.
Definition: iteratorfacades.hh:1460
Codim specific typedefs.
Definition: subdomain.hh:389
Codim specific typedefs.
Definition: subdomain.hh:160
Codim specific typedefs.
Definition: subdomain.hh:545
A set of PartitionType values.
Definition: partitionset.hh:137
static constexpr PartitionIteratorType partitionIterator()
Returns the PartitionIteratorType that can be used to iterate over the partitions in the set.
Definition: partitionset.hh:182
A unique label for each type of element that can occur in a grid.
Helper classes to provide indices for geometrytypes for use in a vector.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Sep 3, 22:42, 2025)