KASKADE 7 development version
embedded_errorest.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-2024 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 EMBEDDED_ERROREST_HH
14#define EMBEDDED_ERROREST_HH
15
16#include <type_traits>
17#include "boost/multi_array.hpp"
18
19#include "fem/errorest.hh"
20#include "fem/fixfusion.hh"
21#include "fem/iterate_grid.hh"
22#include "utilities/power.hh"
23#include "utilities/timing.hh"
24
25namespace Kaskade
26{
28 namespace EmbeddedErrorestimatorDetail
29 {
30
31 using namespace boost::fusion;
32
33 struct GetProjections
34 {
35 template <class Evaluator>
36 typename Evaluator::Space::Mapper::ShapeFunctionSet::Matrix operator()(Evaluator const& evaluator) const
37 {
38 typename Evaluator::Space::Mapper::ShapeFunctionSet::Matrix p = evaluator.shapeFunctions().hierarchicProjection();
39 evaluator.combiner().rightTransform(p);
40 evaluator.combiner().leftPseudoInverse(p);
41 return p;
42 }
43 };
44
45
46 template <class Pairs>
47 struct ApplyProjections
48 {
49 ApplyProjections(Pairs const& data_): data(data_) {}
50
51 template <class Pair>
52 void operator()(Pair const& var) const
53 {
54 int const sid = std::remove_reference<typename boost::fusion::result_of::value_at_c<Pair,0>::type>::type::spaceIndex;
55
56 typedef typename boost::fusion::result_of::value_at_c<Pairs,sid>::type DataPair;
57 typename boost::fusion::result_of::value_at_c<DataPair,0>::type evaluator = at_c<0>(at_c<sid>(data));
58 typename boost::fusion::result_of::value_at_c<DataPair,1>::type p = at_c<1>(at_c<sid>(data));
59
60 typedef typename std::remove_reference<typename boost::fusion::result_of::value_at_c<Pair,1>::type>::type Function;
61 Function& f = at_c<1>(var);
62 typename Function::StorageType x(p.N());
63
64 for (int i=0; i<p.N(); ++i) {
65 x[i] = 0;
66 for (int j=0; j<p.M(); ++j)
67 x[i].axpy(p[i][j][0][0],f.coefficients()[evaluator.globalIndices()[j]]);
68 }
69 for (int i=0; i<p.N(); ++i) {
70 f.coefficients()[evaluator.globalIndices()[i]] = x[i];
71 }
72 }
73
74 private:
75 Pairs const& data;
76 };
77
78 template <class Sequence>
79 ApplyProjections<Sequence> applyProjections(Sequence const& data)
80 {
81 return ApplyProjections<Sequence>(data);
82 }
83
84
85
86 }; // end of namespace EmbeddedErrorestimatorDetail
88
99 template <class VariableSetDescription>
101 {
102 using namespace boost::fusion;
103 using namespace EmbeddedErrorestimatorDetail;
104
105 // Step through all cells.
106 typedef typename VariableSetDescription::Spaces Spaces;
107 typedef typename SpaceType<Spaces,0>::type::Scalar Scalar;
108 typedef typename VariableSetDescription::Grid Grid;
109 typedef typename VariableSetDescription::GridView GridView;
110
111 GridView const& gridView = f.descriptions.gridView ;
112
113 // Evaluators for shape functions of all FE spaces. Remember that
114 // every thread has to use its own collection of evaluators!
115 typedef ShapeFunctionCache<Grid,Scalar> SfCache;
116 auto evaluators = getEvaluators(f.descriptions.spaces,static_cast<SfCache*>(nullptr));
117 using Evaluators = decltype(evaluators);
118
119
120 // A sequence of projection matrices.
121 typedef typename boost::fusion::result_of::as_vector<
122 typename boost::fusion::result_of::transform<Evaluators,GetProjections>::type
123 >::type Projections;
124 Projections projections;
125
126 // Step through all cells. On each cell, compute K^+ P K a, where a
127 // is the coefficient vector, K the combiner (often the identity),
128 // and P the projection matrix that projects to a subspace of lower
129 // order shape functions.
130 for (auto ci=gridView.template begin<0,Dune::All_Partition>();
131 ci!=gridView.template end<0,Dune::All_Partition>(); ++ci) {
132 // for all spaces involved, compute the shape functions and
133 // their global indices, which are needed for evaluating the
134 // functional's derivative.
135 moveEvaluatorsToCell(evaluators,*ci);
136
137 // Compute projections.
138 projections = transform(evaluators,GetProjections());
139
140 // Apply projections.
142 for_each2(vars,f.data,
143 applyProjections(zip(evaluators,projections)));
144 }
145 }
146
147 //---------------------------------------------------------------------
148 // Embedded error estimation.
150 namespace EmbeddedErrorestDetail
151 {
152
153 // A policy class for the GroupedSummationCollector. This declares each cell
154 // a group of its own.
155 class CellByCell
156 {
157 public:
158 template <class IndexSet>
159 CellByCell(IndexSet const& is): nGroups(is.size(0)) {}
160
161 size_t operator[](size_t idx) const { assert(idx<nGroups); return idx; }
162
163 size_t nGroups;
164 };
165
166 // --------------------------------------------------------------------------------------------
167
178 template <class F>
179 class MaximumCollector
180 {
181 public:
187 MaximumCollector(F const& f_, size_t n_)
188 : f(f_)
189 , n(n_)
190 {}
191
192 template <class Cell>
193 int integrationOrder(Cell const&, int shapeFunctionOrder) const
194 {
195 return shapeFunctionOrder;
196 }
197
198 void join(MaximumCollector& c)
199 {
200 if (eps.empty()) // no own data
201 eps = std::move(c.eps); // -> just move here
202 else if (!c.eps.empty()) // both data exist
203 { // -> merge both
204 assert(eps.size()==c.eps.size()); // if coming from partitioned
205 for (size_t i=0; i<eps.size(); ++i) // multithreading, they are complementary
206 eps[i] = std::max(eps[i],c.eps[i]); // but for generality we extend taking the
207 } // maximum nevertheless
208 } // own data but no other data -> nothing to do
209
210 template <class Cell, class Index, class LocalPosition, class Values>
211 void operator()(Cell const& cell, Index idx, LocalPosition const& /* xi */,
212 double /* weight */, Values const& u)
213 {
214 if (eps.empty())
215 eps.resize(n);
216 eps[idx] = std::max(eps[idx],double(f(u)));
217 }
218
219 std::vector<double> const& epsilon() const
220 {
221 return eps;
222 }
223
224 private:
225 F f;
226 size_t n; // number of cells
227 std::vector<double> eps; // cell maximum
228 };
229 } // End of namespace EmbeddedErrorestDetail
231
252 template <class VariableSet, class GridManager>
253 std::array<size_t,3>
256 GridManager& gridManager,
257 double rhoMin=0.1, double rhoMax=0.9)
258 {
259 ScopedTimingSection timing("uniform embedded error estimation");
260
261 auto const& varDesc = u.descriptions;
262
263 timing.timer().start("project hierarchically");
264 auto du = u; // Get the embedded error estimate by projecting
265 projectHierarchically(du); // to lower order and taking the difference.
266 du -= u; // (Note that the sign doesn't matter, we use norms.)
267 timing.timer().stop("project hierarchically");
268
269 timing.timer().start("quantify error");
270 auto const n = varDesc.indexSet.size(0); // number of cells
271 auto f = [&tol](auto const& us) // This maps u to max |u_i|/tol_i.
272 {
273 int i = 0;
274 double epsilon = 0;
275 boost::fusion::for_each(us,[&](auto const& u)
276 { epsilon = std::max(epsilon,u.two_norm() / tol[i++]); });
277 return epsilon;
278 };
279
280 EmbeddedErrorestDetail::MaximumCollector max(f,n); // Find the weighted maximum of all errors
281 gridIterate(du,max); // over the cells.
282 timing.timer().stop("quantify error");
283
284 timing.timer().start("mark");
285 std::array<size_t,3> counts{0,0,0};
286 for (auto const& cell: Dune::elements(varDesc.gridView))
287 {
288 double e = max.epsilon()[varDesc.indexSet.index(cell)];
289 gridManager.mark(e>rhoMax? 1: e<rhoMin? -1: 0, cell);
290 if (e > 1)
291 ++counts[0];
292 if (e > rhoMax)
293 ++counts[1];
294 else if (e < rhoMin)
295 ++counts[2];
296 }
297 timing.timer().stop("mark");
298
299 return counts;
300 }
301
302 // ----------------------------------------------------------------------------------------------
303
314 template <class VariableSetDescription, class Scaling=IdentityScaling>
316 {
317 public:
320
327 EmbeddedErrorEstimator(GManager& gridManager_, VariableSetDescription const& varDesc_, Scaling const& scaling_=Scaling())
328 : gridManager(gridManager_), varDesc(varDesc_), tol(varDesc.noOfVariables,std::make_pair(0.0,0.01)), scaling(scaling_) {}
329
330
335 typename VariableSetDescription::VariableSet const& sol) const
336 {
337 using namespace boost::fusion;
338 using namespace EmbeddedErrorestDetail;
339
340 assert(size(err.data)==size(sol.data));
341
344 join(err.data,sol.data),varDesc.spaces,scaling,sum);
345
346 int const s = varDesc.noOfVariables;
347 int const n = sum.sums.shape()[0];
348
349 assert(sum.sums.shape()[1]==2*s);
350
351 // Compute scaled L2 norms of solution and errors.
352 std::vector<double> norm2(s), error2(s);
353 for (int idx=0; idx<n; ++idx)
354 for (int j=0; j<s; ++j) {
355 error2[j] += sum.sums[idx][j];
356 norm2[j] += sum.sums[idx][j+s];
357 }
358
359
360 if (verbosity>0)
361 {
362 std::cout << " ||solution||^2 = " << std::scientific << std::setprecision(3); std::copy(norm2.begin(),norm2.end(),std::ostream_iterator<double>(std::cout," "));
363 std::cout << std::endl;
364 std::cout << " ||errors||^2 = "; std::copy(error2.begin(),error2.end(),std::ostream_iterator<double>(std::cout," "));
365 std::cout << std::resetiosflags( ::std::ios::scientific ) << std::setprecision(6) << std::endl;
366 };
367
368 // Compute error limit and normalized errors
369 std::vector<double> errorLimit(s);
370 boost::multi_array<double,2> normalizedErrors(boost::extents[n][s]);
371
372 for (int j=0; j<s; ++j)
373 {
374 errorLimit[j] = square(tol[j].first) + square(tol[j].second)*norm2[j];
375 for (int i=0; i<n; ++i)
376 normalizedErrors[i][j] = sum.sums[i][j] / errorLimit[j];
377 }
378
379 // Get refinement thresholds
380 FixedFractionCriterion marker(0.1);
381 auto threshold = marker.threshold(normalizedErrors);
382
383 // Check for refinement necessity
384 if (threshold.empty()) // all variables accurate enough
385 return true;
386
387 // Refine the mesh
388 markAndRefine(gridManager,varDesc.gridView,normalizedErrors,threshold);
389 return false;
390 }
391
401 Self& setTolerances(std::vector<std::pair<double,double> > const& tol_)
402 {
403 tol = tol_;
404 return *this;
405 }
406
410 Self& setScaling(Scaling const& scaling_)
411 {
412 scaling = scaling_;
413 return *this;
414 }
415
420 {
421 criterion = &criterion_;
422 return *this;
423 }
424
432 Self& setVerbosity(int verbosity_)
433 {
434 verbosity = verbosity_;
435 return *this;
436 }
437
438
439 private:
440 GManager& gridManager;
441 VariableSetDescription const& varDesc;
442 std::vector<std::pair<double,double> > tol;
443 Scaling scaling;
444 RefinementCriterion const* criterion;
445 int verbosity;
446 };
447
458 template <class VariableSetDescription, class Scaling>
460 typename VariableSetDescription::VariableSet const& err,
461 typename VariableSetDescription::VariableSet const& sol,
462 Scaling const& scaling,
463 std::vector<std::pair<double,double> > const& tol,
465 int verbosity=1)
466 {
467 EmbeddedErrorEstimator<VariableSetDescription,Scaling> estimator(gridManager,varDesc,scaling);
468 FixedFractionCriterion marker(0.1);
469 estimator.setTolerances(tol).setCriterion(marker).setVerbosity(verbosity);
470 return estimator.estimate(err,sol);
471 }
472} /* end of namespace Kaskade */
473
478#endif
Function is the interface for evaluatable functions .
Definition: concepts.hh:324
Embedded error estimation and mesh refinement.
Fixed fraction refinement criterion. Determines the refinement thresholds such that at least the spec...
Definition: errorest.hh:81
bool mark(int refCount, typename Grid::template Codim< 0 >::Entity const &cell)
Marks the given cell for refinement or coarsening.
Definition: gridmanager.hh:330
Class that takes care of the transfer of data (of each FunctionSpaceElement) after modification of th...
Definition: gridmanager.hh:680
double two_norm() const
euclidean norm
Definition: linearspace.hh:318
Base class for refinement criteria.
Definition: errorest.hh:31
std::vector< double > threshold(boost::multi_array< double, 2 > const &normalizedErrors) const
Computes the thresholds for refinement.
A scope guard object that automatically closes a timing section on destruction.
Definition: timing.hh:181
Timings & timer()
Returns the used timer.
void stop(std::string const &name)
Stops the timing of given section.
struct Times const * start(std::string const &name)
Starts or continues the timing of given section.
A class that stores information about a set of variables.
Definition: variables.hh:537
GridView const & gridView
The grid view on which the variables live.
Definition: variables.hh:812
IndexSet const & indexSet
index set
Definition: variables.hh:820
static int const noOfVariables
Number of variables in this set.
Definition: variables.hh:578
SpaceList Spaces
type of boost::fusion::vector of FEFunctionSpace s needed
Definition: variables.hh:540
Spaces spaces
A heterogeneous sequence of pointers to (const) spaces involved.
Definition: variables.hh:807
typename Variables_Detail::ImplicitIdVariableDescriptions< VariableList >::type Variables
type of boost::fusion vector of VariableDescription s
Definition: variables.hh:543
SpaceType< Spaces, 0 >::type::Grid Grid
Grid type.
Definition: variables.hh:571
SpaceType< Spaces, 0 >::type::GridView GridView
Grid view type.
Definition: variables.hh:573
A class for storing a heterogeneous collection of FunctionSpaceElement s.
Definition: variables.hh:341
Descriptions const & descriptions
Descriptions of variable set, of type VariableSetDescription (lots of useful infos)
Definition: variables.hh:510
A callable that allows to implement weighted (scaled) norms.
Definition: concepts.hh:405
void for_each2(Seq1 const &s1, Seq2 &s2, Func const &func)
Definition: fixfusion.hh:28
std::array< size_t, 3 > uniformEmbeddedErrorEstimation(VariableSet const &u, Dune::FieldVector< double, VariableSet::Descriptions::noOfVariables > const &tol, GridManager &gridManager, double rhoMin=0.1, double rhoMax=0.9)
Embedded error estimation and simultaneous mesh refinement/coarsening.
EmbeddedErrorEstimator< VariableSetDescription, Scaling > Self
Self & setTolerances(std::vector< std::pair< double, double > > const &tol_)
set the tolerances
GridManager< typename VariableSetDescription::Grid > GManager
Self & setCriterion(RefinementCriterion const &criterion_)
set the refinement criterion
Self & setScaling(Scaling const &scaling_)
set the scaling
Self & setVerbosity(int verbosity_)
set the verbosity level
EmbeddedErrorEstimator(GManager &gridManager_, VariableSetDescription const &varDesc_, Scaling const &scaling_=Scaling())
Constructor.
void projectHierarchically(VariableSet< VariableSetDescription > &f)
Projects the given FE function onto the the polynomial ansatz subspace of one order lower....
bool embeddedErrorEstimator(VariableSetDescription const &varDesc, typename VariableSetDescription::VariableSet const &err, typename VariableSetDescription::VariableSet const &sol, Scaling const &scaling, std::vector< std::pair< double, double > > const &tol, GridManager< typename VariableSetDescription::Grid > &gridManager, int verbosity=1)
Embedded error estimation and mesh refinement.
bool estimate(typename VariableSetDescription::VariableSet const &err, typename VariableSetDescription::VariableSet const &sol) const
perform error estimation
typename boost::fusion::result_of::as_vector< typename boost::fusion::result_of::transform< Spaces, GetEvaluatorTypes >::type >::type Evaluators
the heterogeneous sequence type of Evaluators for the given spaces
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Definition: gridBasics.hh:35
Dune::FieldVector< typename GridView::ctype, GridView::dimension > LocalPosition
The type of local positions within cells of the grid view.
Definition: gridBasics.hh:59
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
void markAndRefine(GridManager &gridManager, GridView const &gridView, boost::multi_array< double, 2 > const &normalizedErrors, std::vector< double > const &threshold)
Refines the grid according to the normalized errors and the given thresholds.
Definition: errorest.hh:53
R square(R x)
returns the square of its argument.
Definition: power.hh:49
void axpy(Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, 1, 1 > > const &P, Dune::BlockVector< Dune::FieldVector< Scalar, n > > const &x, Dune::BlockVector< Dune::FieldVector< Scalar, n > > &y, Scalar alpha=1.0)
Compute . If resetSolution=true computes .
void gridIterate(VariableList const &vars, Functions const &functions, Spaces const &spaces, Collector &f)
A function that supports general iterations over a spatial domain and supports efficient evaluation o...
void scaledTwoNormSquared(Variables const &varDesc, Functions const &f, Spaces const &spaces, Scaling const &scaling, Collector &sum)
Evaluates the square of the scaled -norms of a set of functions.
void moveEvaluatorsToCell(Evaluators &evals, Cell const &cell)
Moves all provided evaluators to the given cell.
A Collector coalescing the information of multi-variable functions on cell groups.
Definition: errorest.hh:156
boost::multi_array< double, 2 > sums
Definition: errorest.hh:210
Extracts the type of FE space with given index from set of spaces.