Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
fractionalmarking.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM 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_FUFEM_FRACTIONAL_MARKING_HH
8#define DUNE_FUFEM_FRACTIONAL_MARKING_HH
9
10#include <vector>
11#include <limits>
12
15
18
20
22template <class GridType, class field_type = double>
24{
26 enum {dim = GridType::dimension};
27
29 template<int localDim>
30 struct P0Layout
31 {
32 bool contains (Dune::GeometryType gt) {
33 return gt.dim() == localDim;
34 }
35 };
36
37public:
38 static void mark(RefinementIndicator<GridType>& refinementIndicator,
39 GridType& grid,
40 field_type fraction);
41
52 // TODO: IMHO the implementation does not provide a mechanism that prevents
53 // refining elements where all associated errors are zero.
54 static void mark(const std::vector<std::shared_ptr<RefinementIndicator<GridType> > >& refinementIndicator,
55 const std::vector<GridType*>& grids,
56 field_type fraction);
57
58};
59
60template <class GridType, class field_type>
62mark(RefinementIndicator<GridType>& refinementIndicator,
63 GridType& grid,
64 field_type fraction)
65{
66 std::vector<std::shared_ptr<RefinementIndicator<GridType> > > refinementIndicatorInVector(1);
67 refinementIndicatorInVector[0] = Dune::stackobject_to_shared_ptr<RefinementIndicator<GridType> >(refinementIndicator);
68
69 std::vector<GridType*> gridInVector(1);
70 gridInVector[0] = &grid;
71
72 mark(refinementIndicatorInVector, gridInVector, fraction);
73}
74
75template <class GridType, class field_type>
78 const std::vector<GridType*>& grids,
79 field_type fraction)
80{
81 if (grids.size() != refinementIndicators.size())
82 DUNE_THROW(Dune::Exception, "The number of grids must match the number of error sets");
83
84 // /////////////////////////////////////////////////////////////////
85 // Create a map which stores the error for all elements of
86 // all grids and which can be traversed in sorted order.
87 // /////////////////////////////////////////////////////////////////
89 using Iterator = typename std::multimap<field_type, std::pair<int,int> >::reverse_iterator;
90
91 std::vector<field_type> minGridError(grids.size()), maxGridError(grids.size());
92
93 for (size_t i=0; i<grids.size(); i++) {
94
95 minGridError[i] = std::numeric_limits<field_type>::max();
96 maxGridError[i] = -std::numeric_limits<field_type>::max();
97
99
100 const auto& leafView = grids[i]->leafGridView();
101
102 for (const auto& e : elements(leafView)) {
103
104 // Get set of shape functions
105 const auto& refElement = Dune::ReferenceElements<field_type, dim>::general(e.type());
106
107 // Compute the maximum indicator of any subentity of this element
108 field_type maxError = 0;
109 for (int codim=0; codim<=dim; codim++)
110 for (int entity=0; entity<refElement.size(codim); entity++)
111 maxError = std::max(maxError, (*refinementIndicators[i]).value(e, codim, entity));
112
113 // Store the max error in a map ordered by the error
114 errorMap.insert(std::pair<field_type, std::pair<int,int> >(maxError, std::make_pair(i, p0Mapper.index(e))));
115
116 minGridError[i] = std::min(minGridError[i], maxError);
117 maxGridError[i] = std::max(maxGridError[i], maxError);
118
119 }
120
121 }
122
123 std::cout << "Errors per grid:" << std::endl;
124 for (size_t i=0; i<grids.size(); i++)
125 std::cout << i << ": " << minGridError[i] << " -- " << maxGridError[i] << std::endl;
126
127 // //////////////////////////////////////////////////////////////////////
128 // Mark the desired fraction of elements with the highest error in
129 // bitfields. This is more memory efficient than storing EntityPointers
130 // in the map.
131 // //////////////////////////////////////////////////////////////////////
132
133 int numElementsToBeRefined = int(std::ceil(errorMap.size()*fraction));
134
135 if (numElementsToBeRefined > int(errorMap.size()))
136 DUNE_THROW(Dune::Exception, "fraction can't be more than one");
137
138 std::vector<Dune::BitSetVector<1> > refinedElements(grids.size());
139 for (size_t i=0; i<grids.size(); i++) {
140 refinedElements[i].resize(grids[i]->leafIndexSet().size(0));
141 refinedElements[i].unsetAll();
142 }
143
144 Iterator it = errorMap.rbegin();
145
146 for (int i=0; i<numElementsToBeRefined; i++, ++it) {
147 int grid = it->second.first;
148 int element = it->second.second;
149 refinedElements[grid][element] = true;
150 }
151
152 // /////////////////////////////////////////////////////////////////////
153 // Actually mark the elements for refinement
154 // /////////////////////////////////////////////////////////////////////
155
156 for (size_t i=0; i<grids.size(); i++) {
157
159
160 for (const auto& e : elements(grids[i]->leafGridView()))
161 if (refinedElements[i][p0Mapper.index(e)][0])
162 grids[i]->mark(1,e);
163
164 }
165
166
167}
168#endif
int size() const
size_type dim() const
#define DUNE_THROW(E,...)
MCMGLayout mcmgElementLayout()
Index index(const EntityType &e) const
See static method mark for details.
Definition fractionalmarking.hh:24
static void mark(RefinementIndicator< GridType > &refinementIndicator, GridType &grid, field_type fraction)
Definition fractionalmarking.hh:62
Holds refinement indicators for a hierarchical grid.
Definition refinementindicator.hh:22
T ceil(T... args)
T endl(T... args)
T insert(T... args)
T make_pair(T... args)
T max(T... args)
T min(T... args)
T rbegin(T... args)
T resize(T... args)
T size(T... args)