KASKADE 7 development version
adaptationStrategy.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2013 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef ADAPTATION_STRATEGY_HH
14#define ADAPTATION_STRATEGY_HH
15
16#include <algorithm>
17#include <utility>
18#include <vector>
19
20namespace Kaskade
21{
22 namespace AdaptationStrategy_Detail
23 {
25 {
26 template <class Scalar, class IndexInt>
27 bool operator()(const std::pair<Scalar, IndexInt>& x1, const std::pair<Scalar,IndexInt>& x2)
28 {
29 return fabs(x1.first) > fabs(x2.first);
30 }
31 };
32
33 struct Add
34 {
35 template <class Scalar, class IndexInt>
36 Scalar operator()(Scalar x1, const std::pair<Scalar,IndexInt>& x2)
37 {
38 return x1 + x2.first;
39 }
40 };
41 }
42
43 namespace Adaptivity
44 {
45 template <class Grid>
47 {
48 static constexpr int dim = Grid::dimension;
49 typedef size_t IndexInt;
50 public:
51 template <typename... Args>
52 explicit FixedCellFraction(GridManagerBase<Grid>& gridManager_, double fraction_, Args...)
53 : gridManager(gridManager_), fraction(fraction_)
54 {}
55
56 template <class Err, class ErrorRepresentation, class Scalar>
57 void refineGrid_impl(Err const& err, ErrorRepresentation& errorDistribution, Scalar tol)
58 {
59 std::sort(errorDistribution.begin(), errorDistribution.end(), AdaptationStrategy_Detail::BiggerThanAbs());
60 std::cout << "max error2: " << std::max_element(errorDistribution.begin(), errorDistribution.end())->first << std::endl;
61 std::cout << "min error2: " << std::min_element(errorDistribution.begin(), errorDistribution.end())->first << std::endl;
62
63 std::vector<std::pair<Scalar,IndexInt> > bulkErrorDistribution(errorDistribution.begin(), errorDistribution.begin() + static_cast<size_t>(errorDistribution.size() * fraction));
64 Scalar bulkErrorSquared = std::accumulate(bulkErrorDistribution.begin(),bulkErrorDistribution.end(),0.0,AdaptationStrategy_Detail::Add());
65
66 std::cout << "bulkErrorDistribution.size()=" << bulkErrorDistribution.size() << std::endl;
67 std::cout << "bulkErrorSquared=" << bulkErrorSquared << std::endl;
68 std::cout << "remaining error contribution (squared): " << std::accumulate(errorDistribution.begin()+bulkErrorDistribution.size(),errorDistribution.end(), 0.0, AdaptationStrategy_Detail::Add()) << std::endl;
69
70 // do refinement
71 size_t counter = 0;
72 std::vector<int> visitedCells;
73 auto cend = err.descriptions.gridView.template end<0>();
74 for (auto ci=gridManager.grid().leafGridView().template begin<0>(); ci!=cend; ++ci) // iterate over cells
75 {
76 for(int i=0; i<bulkErrorDistribution.size(); ++i) // iterate over chosen part of the error distribution
77 if(gridManager.grid().leafIndexSet().index(*ci) == bulkErrorDistribution[i].second)
78 {
79
80 visitedCells.push_back(gridManager.grid().leafIndexSet().index(*ci));
81
82 ++counter;
83 gridManager.mark(1,*ci);
84 }
85 }
86
87 std::cout << "FIXED CELL FRACTION: marked " << counter << " of " << gridManager.grid().size(0) << " cells for refinement." << std::endl;
88 gridManager.adaptAtOnce();
89 }
90
91 private:
92 GridManagerBase<Grid>& gridManager;
93 double fraction;
94 };
95
96 template <class Grid>
98 {
99 static constexpr int dim = Grid::dimension;
100 typedef size_t IndexInt;
101 public:
102 template <typename... Args>
103 explicit FixedErrorFraction(GridManagerBase<Grid>& gridManager_, double fraction_, Args...)
104 : gridManager(gridManager_), fraction(fraction_)
105 {}
106
107 template <class Err, class ErrorRepresentation, class Scalar>
108 void refineGrid_impl(Err const& err, ErrorRepresentation& errorDistribution, Scalar tol)
109 {
110 tol *= fraction*fraction;
111 std::cout << "used tolerance: " << tol << std::endl;
112 std::sort(errorDistribution.begin(), errorDistribution.end(), AdaptationStrategy_Detail::BiggerThanAbs());
113 std::cout << "max error2: " << std::max_element(errorDistribution.begin(), errorDistribution.end())->first << std::endl;
114 std::cout << "min error2: " << std::min_element(errorDistribution.begin(), errorDistribution.end())->first << std::endl;
115
116 Scalar bulkErrorSquared = 0;
117 std::vector<std::pair<Scalar,IndexInt> > bulkErrorDistribution;
118
119 while(bulkErrorSquared < tol)
120 {
121 bulkErrorDistribution.push_back(errorDistribution[bulkErrorDistribution.size()]);
122 bulkErrorSquared += bulkErrorDistribution.back().first;
123 }
124
125 std::cout << "bulkErrorDistribution.size()=" << bulkErrorDistribution.size() << std::endl;
126 std::cout << "bulkErrorSquared=" << bulkErrorSquared << std::endl;
127 std::cout << "remaining error contribution (squared): " << std::accumulate(errorDistribution.begin()+bulkErrorDistribution.size(),errorDistribution.end(), 0.0, AdaptationStrategy_Detail::Add()) << std::endl;
128
129 // do refinement
130 size_t counter = 0;
131 std::vector<int> visitedCells;
132 auto cend = err.descriptions.gridView.template end<0>();
133 for (auto ci=gridManager.grid().leafGridView().template begin<0>(); ci!=cend; ++ci) // iterate over cells
134 {
135 for(int i=0; i<bulkErrorDistribution.size(); ++i) // iterate over chosen part of the error distribution
136 if(gridManager.grid().leafIndexSet().index(*ci) == bulkErrorDistribution[i].second)
137 {
138
139 visitedCells.push_back(gridManager.grid().leafIndexSet().index(*ci));
140
141 ++counter;
142 gridManager.mark(1,*ci);
143 }
144 }
145
146 std::cout << "FIXED ERROR FRACTION: marked " << counter << " of " << gridManager.grid().size(0) << " cells for refinement." << std::endl;
147 gridManager.adaptAtOnce();
148 }
149
150 private:
151 GridManagerBase<Grid>& gridManager;
152 double fraction;
153 };
154
155 template <class Grid>
157 {
158 public:
159 template <typename... Args>
160 explicit ErrorEquilibration2(GridManagerBase<Grid>& gridManager_, Args...) : gridManager(gridManager_)
161 {}
162
163 template <class Err, class ErrorRepresentation, class Scalar>
164 void refineGrid_impl(Err const& err, ErrorRepresentation& errorDistribution, Scalar tol)
165 {
166 std::cout << "ERROR EQUILIBRATION" << std::endl;
167 std::sort(errorDistribution.begin(), errorDistribution.end(), AdaptationStrategy_Detail::BiggerThanAbs());
168
169 std::cout << "err distr" << std::endl;
170// for(auto a : errorDistribution) std::cout << errorDistribution.first << ", " <<
171//
172// size_t lastIndex = errorDistribution.size()-1;
173// size_t firstIndex = 0;
174//
175// while(firstIndex+3 < lastIndex)
176// {
177// if(bulkErrorDistribution.size() > 4)
178// {
179// Scalar firstContribution = 15.0/256.0 * errorDistribution[firstIndex].first;
180//
181// Scalar lastContributions = bulkErrorDistribution[lastIndex--].first;
182// lastContributions += bulkErrorDistribution[lastIndex--].first;
183// lastContributions += bulkErrorDistribution[lastIndex].first;
184// lastContributions *= 15.0/16.0;
185//
186// if(lastContributions < firstContribution)
187// {
188// ++lastIndexForDoubleRefinement;
189// ++firstIndex;
190// --lastIndex;
191// bulkErrorDistribution.erase(bulkErrorDistribution.end()-3, bulkErrorDistribution.end());
192// }
193// else break;
194// }
195// }
196 Scalar N2 = gridManager.grid().size(0);
197// N2 *= N2;
198 Scalar relTol = tol/N2;
199 // do refinement
200 auto cend = gridManager.grid().leafGridView().template end<0>();
201 size_t counter = 0;
202 Scalar minErr = errorDistribution.back().first, maxErr = errorDistribution[0].first;
203 //constexpr int dim = ErrorRepresentation::Descriptions::Grid::dimension;
204 //Dune::FieldVector<Scalar,dim> x0(0.2);
205
206 std::cout << "grr" << std::endl;
207 std::cout << "marking cells..." << std::flush;
208 for (auto ci=gridManager.grid().leafGridView().template begin<0>(); ci!=cend; ++ci) // iterate over cells
209 {
210// if(counter > N3) break;
211// std::cout << "counter: " << counter << std::endl;
212// std::cout << "id: " << is.index(*ci) << std::endl;
213// std::cout << "corners: " << std::endl;
214// for(size_t i=0; i<ci->geometry().corners(); ++i) std::cout << "i: " << ci->geometry().corner(i) << std::endl;
215 for(size_t i=0; i<errorDistribution.size(); ++i) // iterate over chosen part of the error distribution
216 if(gridManager.grid().leafIndexSet().index(*ci) == errorDistribution[i].second)
217 {
218// auto const& tmp = boost::fusion::at_c<0>(err.data);
219// std::cout << "gsg" << std::endl;
220// Scalar val = tmp.value(ci->geometry().global(x0));
221// val = std::fabs(val);
222// //Scalar val = boost::fusion::at_c<0>(err.data).value(*ci,x0);
223// std::cout << "val=" << val << std::endl;
224// if(minErr > val) minErr = val;
225// if(maxErr < val) maxErr = val;
226// if(val > relTol){
227// ++counter;
228// gridManager.mark(1,*ci);
229// }
230// if(minErr > errorDistribution[i].first) minErr = errorDistribution[i].first;
231// if(maxErr < errorDistribution[i].first) maxErr = errorDistribution[i].first;
232 if(errorDistribution[i].first > relTol){
233 std::cout << "marking cell at position " << i << std::endl;
234 ++counter;
235 gridManager.mark(1,*ci);
236 }
237 }
238 }
239 std::cout << "done." << std::endl;
240 std::cout << "totalErrorSquared: " << tol << " -> tolerance: " << relTol << std::endl;
241 std::cout << "maxErr: " << maxErr << ", minErr: " << minErr << std::endl;
242 std::cout << "refining " << counter << " of " << gridManager.grid().size(0) << " cells" << std::endl;
243
244 std::cout << "adapting..." << std::flush;
245 gridManager.adaptAtOnce();
246 std::cout << "done." << std::endl;
247 // adjust error function
248 }
249
250 private:
251 GridManagerBase<Grid>& gridManager;
252 };
253
254 template <class Grid>
256 {
257 public:
258 template <typename... Args>
259 explicit ErrorEquilibration(GridManagerBase<Grid>& gridManager_, Args...) : gridManager(gridManager_)
260 {}
261
262 template <class Err, class ErrorRepresentation, class Scalar>
263 void refineGrid_impl(Err const& err, ErrorRepresentation& errorDistribution, Scalar tol)
264 {
265 std::cout << "ERROR EQUILIBRATION" << std::endl;
266 std::sort(errorDistribution.begin(), errorDistribution.end(), AdaptationStrategy_Detail::BiggerThanAbs());
267
268 Scalar n2 = gridManager.grid().size(0);
269 Scalar relTol = tol/n2;
270
271 // do refinement
272 auto cend = gridManager.grid().leafGridView().template end<0>();
273 size_t counter = 0;
274 Scalar minErr = errorDistribution.back().first, maxErr = errorDistribution[0].first;
275 std::vector<size_t> mainContributors;
276 //constexpr int dim = ErrorRepresentation::Descriptions::Grid::dimension;
277 //Dune::FieldVector<Scalar,dim> x0(0.2);
278
279 std::cout << "marking cells..." << std::flush;
280 for (auto ci=gridManager.grid().leafGridView().template begin<0>(); ci!=cend; ++ci) // iterate over cells
281 {
282 for(size_t i=0; i<errorDistribution.size(); ++i) // iterate over chosen part of the error distribution
283 if(gridManager.grid().leafIndexSet().index(*ci) == errorDistribution[i].second)
284 {
285 if(errorDistribution[i].first > relTol){
286 if(errorDistribution[i].first > 4 * relTol) mainContributors.push_back(errorDistribution[i].second);
287 ++counter;
288 gridManager.mark(1,*ci);
289 }
290 }
291 }
292 std::cout << "done." << std::endl;
293 std::cout << "totalErrorSquared: " << tol << " -> tolerance: " << relTol << std::endl;
294 std::cout << "maxErr: " << maxErr << ", minErr: " << minErr << std::endl;
295 std::cout << "refining " << counter << " of " << gridManager.grid().size(0) << " cells" << std::endl;
296
297 std::cout << "adapting..." << std::flush;
298 gridManager.adaptAtOnce();
299 std::cout << "done." << std::endl;
300
301 /* std::cout << "second refinement" << std::endl;
302 auto cend2 = gridManager.grid().leafGridView().template end<0>();
303 for(auto ci=gridManager.grid().leafGridView().template begin<0>(); ci!=cend2; ++ci)
304 {
305 if(ci->level() > 0)
306 {
307 auto father = ci->father();
308 if(ci->level() > father->level())
309 for(size_t i : mainContributors) if(i == gridManager.grid().levelIndexSet(gridManager.grid().maxLevel()-1).index(*father)) { gridManager.mark(1,*ci); return; }
310 }
311 }
312
313 std::cout << "adapting..." << std::flush;
314 gridManager.adaptAtOnce();
315 std::cout << "done." << std::endl;*/
316 }
317
318 private:
319 GridManagerBase<Grid>& gridManager;
320 };
321 } // end namespace Adaptivity
322} // end namespace Kaskade
323
324#endif
ErrorEquilibration2(GridManagerBase< Grid > &gridManager_, Args...)
void refineGrid_impl(Err const &err, ErrorRepresentation &errorDistribution, Scalar tol)
void refineGrid_impl(Err const &err, ErrorRepresentation &errorDistribution, Scalar tol)
ErrorEquilibration(GridManagerBase< Grid > &gridManager_, Args...)
void refineGrid_impl(Err const &err, ErrorRepresentation &errorDistribution, Scalar tol)
FixedCellFraction(GridManagerBase< Grid > &gridManager_, double fraction_, Args...)
void refineGrid_impl(Err const &err, ErrorRepresentation &errorDistribution, Scalar tol)
FixedErrorFraction(GridManagerBase< Grid > &gridManager_, double fraction_, Args...)
Grid const & grid() const
Returns a const reference on the owned grid.
Definition: gridmanager.hh:292
bool adaptAtOnce()
DEPRECATED Performs grid refinement without prolongating registered FE functions.
Definition: gridmanager.hh:390
bool mark(int refCount, typename Grid::template Codim< 0 >::Entity const &cell)
Marks the given cell for refinement or coarsening.
Definition: gridmanager.hh:330
Scalar operator()(Scalar x1, const std::pair< Scalar, IndexInt > &x2)
bool operator()(const std::pair< Scalar, IndexInt > &x1, const std::pair< Scalar, IndexInt > &x2)