Dune-Functions 2.11
Loading...
Searching...
No Matches
mapperutilities.hh
Go to the documentation of this file.
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_MAPPERUTILITIES_HH
8#define DUNE_FUNCTIONS_COMMON_MAPPERUTILITIES_HH
9
10#include <vector>
11#include <bitset>
12
13#include <dune/common/rangeutilities.hh>
14
15#include <dune/grid/common/rangegenerators.hh>
16#include <dune/grid/common/mcmgmapper.hh>
17
18namespace Dune::Functions {
19
20// All utilities are in Impl:: and thus considered implementation
21// details for now. However, one may want to think about making
22// them public. Then they could also be put into dune-grid,
23// since there's nothing dune-function specific about them.
24namespace Impl {
25
26
27
28 // Helper class providing an unordered range
29 // of global indices associated to the element
30 // within a MultipleCodimMultipleGeomTypeMapper.
31 // This has to be bound to an element, before
32 // it can be used.
33 template<class GV>
34 class MapperElementSubIndices
35 {
36 using IndexContainer = std::vector<typename Dune::MultipleCodimMultipleGeomTypeMapper<GV>::Index>;
37 public:
38 using GridView = GV;
39 using Mapper = Dune::MultipleCodimMultipleGeomTypeMapper<GridView>;
40 using Index = typename Mapper::Index;
41 using Element = typename GridView::template Codim<0>::Entity;
42
43 MapperElementSubIndices(const Mapper& mapper)
44 : mapper_(mapper)
45 {}
46
47 // Bind to given element and precompute all indices.
48 void bind(const Element& element)
49 {
50 constexpr auto dimension = GridView::dimension;
51 indices_.clear();
52 auto referenceElement = Dune::referenceElement<double, dimension>(element.type());
53 for (auto codim : Dune::range(dimension + 1)) {
54 for (auto subEntity : Dune::range(referenceElement.size(codim))) {
55 std::size_t c = mapper_.layout()(referenceElement.type(subEntity, codim), dimension);
56 if (c > 0) {
57 std::size_t firstIndex = mapper_.subIndex(element, subEntity, codim);
58 for (auto j : Dune::range(firstIndex, firstIndex + c)) {
59 indices_.push_back(j);
60 }
61 }
62 }
63 }
64 }
65
66 auto begin() const
67 {
68 return indices_.begin();
69 }
70
71 auto end() const
72 {
73 return indices_.end();
74 }
75
76 private:
77 const Mapper mapper_;
78 IndexContainer indices_;
79 };
80
81
82
83 // Helper function computing an average mesh size per subentity
84 // by averaging over the adjacent elements. This only considers
85 // the subentities handled by the given mapper and returns a
86 // std::vector<FieldType> of mesh sizes indexed according to the mapper.
87 //
88 // The average is determined by first computing the average volume
89 // of adjacent elements and then taking the d-th root for a d-dimensional
90 // grid.
91 //
92 // This operation has O(n) runtime (with n=mapper.size()),
93 // allocates O(n) memory for the returned vector and additional
94 // O(n) temporary memory.
95 template<class FieldType = double, class Mapper>
96 auto computeAverageSubEntityMeshSize(const Mapper& mapper)
97 {
98 constexpr auto dimension = Mapper::GridView::dimension;
99 std::vector<unsigned int> adjacentElements(mapper.size(), 0);
100 std::vector<FieldType> subEntityMeshSize(mapper.size(), 0.0);
101 auto subIndices = Impl::MapperElementSubIndices(mapper);
102 for(const auto& element : Dune::elements(mapper.gridView()))
103 {
104 auto A = element.geometry().volume();
105 subIndices.bind(element);
106 for(auto i : subIndices)
107 {
108 subEntityMeshSize[i] += A;
109 ++(adjacentElements[i]);
110 }
111 }
112 for(auto i : Dune::range(mapper.size()))
113 subEntityMeshSize[i] = std::pow(subEntityMeshSize[i]/adjacentElements[i], 1./dimension);
114 return subEntityMeshSize;
115 }
116
128 template<class ElementMapper>
129 std::vector<std::bitset<3>> computeEdgeOrientations(ElementMapper mapper)
130 {
131 constexpr int dim = 2;
132 static_assert(dim == ElementMapper::GridView::dimension);
133
134 auto const& gridView = mapper.gridView();
135 std::vector<std::bitset<3>> orientations;
136 orientations.resize(gridView.size(0));
137 // compute orientation for all elements
138 auto const& idSet = gridView.grid().globalIdSet();
139
140 for (const auto &element : elements(gridView))
141 {
142 const auto &refElement = referenceElement(element);
143 auto elementIndex = mapper.index(element);
144
145 std::bitset<3>& orientation = orientations[elementIndex];
146
147
148 for (std::size_t i = 0; i < element.subEntities(dim - 1); i++)
149 {
150 // Local vertex indices within the element are ordered, localV0 < localV1
151 auto localV0 = refElement.subEntity(i, dim - 1, 0, dim);
152 auto localV1 = refElement.subEntity(i, dim - 1, 1, dim);
153
154 // Global vertex indices within the grid
155 auto globalV0 = idSet.subId(element, localV0, dim);
156 auto globalV1 = idSet.subId(element, localV1, dim);
157
158 // The edge is flipped if the local ordering disagrees with global ordering
159 orientation[i] = globalV0 > globalV1;
160 }
161 }
162 return orientations;
163 }
164
165} // end namespace Impl
166
167} // end namespace Dune::Functions
168
169
170#endif // end namespace DUNE_FUNCTIONS_COMMON_MAPPERUTILITIES_HH
auto elements(const SubDomainGridView< HostGridView > &subDomainGridView)
ADL findable access to element range for a SubDomainGridView.
Definition subdomain.hh:487
Definition monomialset.hh:19