Marker.hpp 10.8 KB
Newer Older
1
#pragma once
2

Praetorius, Simon's avatar
Praetorius, Simon committed
3
#include <limits>
4
#include <string>
Praetorius, Simon's avatar
Praetorius, Simon committed
5
#include <utility>
6

Praetorius, Simon's avatar
Praetorius, Simon committed
7
#include <dune/common/std/optional.hh>
8
9
#include <dune/grid/common/grid.hh>

Praetorius, Simon's avatar
Praetorius, Simon committed
10
#include <amdis/common/ConceptsBase.hpp>
11
#include <amdis/common/TypeTraits.hpp>
Praetorius, Simon's avatar
Praetorius, Simon committed
12
13
14

#include <amdis/gridfunctions/GridFunctionConcepts.hpp>

15
16
17
18
#include <amdis/AdaptInfo.hpp>
#include <amdis/Flag.hpp>
#include <amdis/Initfile.hpp>

Praetorius, Simon's avatar
Praetorius, Simon committed
19
20
namespace AMDiS
{
21
22
23
24
  /**
   * \ingroup Adaption
   *
   * \brief
Praetorius, Simon's avatar
Praetorius, Simon committed
25
   * Base class for all markers.
26
   */
Praetorius, Simon's avatar
Praetorius, Simon committed
27
  template <class Grid>
28
29
  class Marker
  {
30
  protected:
Praetorius, Simon's avatar
Praetorius, Simon committed
31
    using GridView = typename Grid::LeafGridView;
32
33
34
35
    using Element  = typename GridView::template Codim<0>::Entity;

  public:
    /// Constructor.
Praetorius, Simon's avatar
Praetorius, Simon committed
36
    Marker() = default;
37
38

    /// Constructor.
Praetorius, Simon's avatar
Praetorius, Simon committed
39
    Marker(std::string const& name, std::shared_ptr<Grid> const& grid)
40
41
      : name_(name)
      , grid_(grid)
42
    {
43
44
45
      Parameters::get(name + "->info", info_);
      Parameters::get(name + "->max refinement level", maxRefineLevel_);
      Parameters::get(name + "->min refinement level", minRefineLevel_);
46
47
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
48
49
    /// Destructor.
    virtual ~Marker() = default;
50

51
    /// Marks element with newMark. If \ref maximumMarking_ is set, the element
52
53
    /// is marked only if the new mark is bigger than the old one. The return
    /// value specifies whether the element has been marked, or not.
Praetorius, Simon's avatar
Praetorius, Simon committed
54
    void mark(Element const& elem, int newMark);
55

Praetorius, Simon's avatar
Praetorius, Simon committed
56
    /// Called before traversal.
57
58
    virtual void initMarking(AdaptInfo& adaptInfo);

Praetorius, Simon's avatar
Praetorius, Simon committed
59
    /// Called after traversal.
60
61
62
    virtual void finishMarking(AdaptInfo& adaptInfo);

    /// Marks one element.
Praetorius, Simon's avatar
Praetorius, Simon committed
63
    virtual void markElement(AdaptInfo& adaptInfo, Element const& elem) = 0;
64

Praetorius, Simon's avatar
Praetorius, Simon committed
65
    /// Marking of the whole grid.
66
67
    virtual Flag markGrid(AdaptInfo& adaptInfo);

Praetorius, Simon's avatar
Praetorius, Simon committed
68
    /// Returns \ref elMarkRefine_ of the Marker
Praetorius, Simon's avatar
Praetorius, Simon committed
69
    int elMarkRefine() const
70
    {
71
      return elMarkRefine_;
72
73
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
74
    /// Returns \ref elMarkCoarsen_ of the Marker
Praetorius, Simon's avatar
Praetorius, Simon committed
75
    int elMarkCoarsen() const
76
    {
77
      return elMarkCoarsen_;
78
79
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
80
    /// Returns \ref name_ of the Marker
Praetorius, Simon's avatar
Praetorius, Simon committed
81
    std::string const& name() const
82
    {
83
      return name_;
84
85
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    /// Sets \ref maximumMarking_.
    void setMaximumMarking(bool maxMark)
    {
      maximumMarking_ = maxMark;
    }

    /// Sets \ref refineAllowed_.
    void allowRefinement(bool allow)
    {
      refineAllowed_ = allow;
    }

    /// Sets \ref coarsenAllowed_.
    void allowCoarsening(bool allow)
    {
      coarsenAllowed_ = allow;
    }
103
104

  protected:
Praetorius, Simon's avatar
Praetorius, Simon committed
105
    /// Name of the marker.
106
    std::string name_;
107
108

    /// Pointer to the grid
109
    std::shared_ptr<Grid> grid_;
110
111
112

    /// If true, elements are marked only if the new value is bigger than
    /// the current marking.
Praetorius, Simon's avatar
Praetorius, Simon committed
113
    bool maximumMarking_ = false;
114
115

    /// Info level.
Praetorius, Simon's avatar
Praetorius, Simon committed
116
    int info_ = 0;
117
118

    /// Counter for elements marked for refinement
119
    int elMarkRefine_ = 0;
120
121

    /// Counter for elements marked for coarsening
122
    int elMarkCoarsen_ = 0;
123
124

    /// Maximal level of all elements.
125
    int maxRefineLevel_ = std::numeric_limits<int>::max();
126
127

    /// Minimal level of all elements.
128
    int minRefineLevel_ = 0;
129

Praetorius, Simon's avatar
Praetorius, Simon committed
130
    /// Allow elements to be marked for refinement
131
    bool refineAllowed_ = true;
132

Praetorius, Simon's avatar
Praetorius, Simon committed
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    /// Allow elements to be marked for coarsening
    bool coarsenAllowed_ = true;
  };


  /**
   * \ingroup Adaption
   *
   * \brief
   * Base class for all estimator-based markers.
   */
  template <class Grid>
  class EstimatorMarker
      : public Marker<Grid>
  {
  protected:
    using Super = Marker<Grid>;
    using Element   = typename Super::Element;
    using Estimates = std::vector<double>;

  public:
    /// Constructor.
    EstimatorMarker() = default;

    /// Constructor.
    EstimatorMarker(std::string name, std::string component, Estimates const& est,
                    std::shared_ptr<Grid> const& grid)
      : Super{std::move(name), grid}
      , component_(std::move(component))
      , est_(est)
    {
      Parameters::get(this->name_ + "->p", p_);
    }

    /// Can be used by sub classes. Called before traversal.
168
    void initMarking(AdaptInfo& adaptInfo) override;
Praetorius, Simon's avatar
Praetorius, Simon committed
169
170

    /// Marks one element.
171
    void markElement(AdaptInfo& adaptInfo, Element const& elem) override;
Praetorius, Simon's avatar
Praetorius, Simon committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199

    /// Creates a scalar marker depending on the strategy set in parameters.
    static std::unique_ptr<EstimatorMarker<Grid> > createMarker(std::string const& name,
      std::string const& component, Estimates const& est, std::shared_ptr<Grid> const& grid);

  protected:
    /// Problem component to work on
    std::string component_;

    /// Pointer to the local error estimates
    Estimates est_;

    /// Estimation sum
    double estSum_ = 0.0;

    /// Estmation maximum
    double estMax_ = 0.0;

    /// Lower limit for error estimation, from which an element is marked for
    /// refinement
    double markRLimit_;

    /// Upper limit for error estimation, from which an element is marked for
    /// coarsening
    double markCLimit_;

    /// Power in estimator norm
    double p_ = 2.0;
200
201
202
203
204
205
206
207
208
  };


  /**
   * \ingroup Adaption
   *
   * \brief
   * Global refinement.
   */
Praetorius, Simon's avatar
Praetorius, Simon committed
209
  template <class Grid>
210
  class GRMarker
Praetorius, Simon's avatar
Praetorius, Simon committed
211
      : public EstimatorMarker<Grid>
212
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
213
    using Super = EstimatorMarker<Grid>;
214
215
    using Element   = typename Super::Element;
    using Estimates = typename Super::Estimates;
216
217
218

  public:
    /// Constructor.
Praetorius, Simon's avatar
Praetorius, Simon committed
219
    GRMarker(std::string const& name, std::string const& component, Estimates const& est,
220
             std::shared_ptr<Grid> const& grid)
Praetorius, Simon's avatar
Praetorius, Simon committed
221
      : Super{name, component, est, grid}
222
223
    {}

224
    void markElement(AdaptInfo& adaptInfo, Element const& elem) override
225
    {
226
      if (this->refineAllowed_)
227
228
229
230
231
232
233
234
235
236
237
        this->mark(elem, 1);
    }
  };


  /**
   * \ingroup Adaption
   *
   * \brief
   * Maximum strategy.
   */
238

Praetorius, Simon's avatar
Praetorius, Simon committed
239
  template <class Grid>
240
  class MSMarker
Praetorius, Simon's avatar
Praetorius, Simon committed
241
      : public EstimatorMarker<Grid>
242
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
243
    using Super = EstimatorMarker<Grid>;
244
    using Estimates = typename Super::Estimates;
245
246
247

  public:
    /// Constructor.
248
    MSMarker(std::string const& name, std::string component, Estimates const& est,
249
             std::shared_ptr<Grid> const& grid)
250
      : Super{name, std::move(component), est, grid}
251
    {
252
253
      Parameters::get(name + "->MSGamma", msGamma_);
      Parameters::get(name + "->MSGammaC", msGammaC_);
254
255
    }

256
    void initMarking(AdaptInfo& adaptInfo) override;
257
258
259

  protected:
    /// Marking parameter.
260
    double msGamma_ = 0.5;
261
262

    /// Marking parameter.
263
    double msGammaC_ = 0.1;
264
265
266
267
268
269
270
271
272
  };


  /**
   * \ingroup Adaption
   *
   * \brief
   * Equidistribution strategy
   */
273

Praetorius, Simon's avatar
Praetorius, Simon committed
274
  template <class Grid>
275
  class ESMarker
Praetorius, Simon's avatar
Praetorius, Simon committed
276
      : public EstimatorMarker<Grid>
277
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
278
    using Super = EstimatorMarker<Grid>;
279
    using Estimates = typename Super::Estimates;
280
281
282

  public:
    /// Constructor.
283
    ESMarker(std::string const& name, std::string component, Estimates const& est,
284
             std::shared_ptr<Grid> const& grid)
285
      : Super{name, std::move(component), est, grid}
286
    {
287
288
      Parameters::get(name + "->ESTheta", esTheta_);
      Parameters::get(name + "->ESThetaC", esThetaC_);
289
290
    }

291
    void initMarking(AdaptInfo& adaptInfo) override;
292
293
294

  protected:
    /// Marking parameter.
295
    double esTheta_ = 0.9;
296
297

    /// Marking parameter.
298
    double esThetaC_ = 0.2;
299
300
301
302
303
304
305
306
307
  };


  /**
   * \ingroup Adaption
   *
   * \brief
   * Guaranteed error reduction strategy
   */
308

Praetorius, Simon's avatar
Praetorius, Simon committed
309
  template <class Grid>
310
  class GERSMarker
Praetorius, Simon's avatar
Praetorius, Simon committed
311
      : public EstimatorMarker<Grid>
312
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
313
    using Super = EstimatorMarker<Grid>;
314
315
    using Element   = typename Super::Element;
    using Estimates = typename Super::Estimates;
316
317
318

  public:
    /// Constructor.
319
    GERSMarker(std::string const& name, std::string component, Estimates const& est,
320
               std::shared_ptr<Grid> const& grid)
321
      : Super{name, std::move(component), est, grid}
322
    {
323
324
325
      Parameters::get(name + "->GERSThetaStar", gersThetaStar_);
      Parameters::get(name + "->GERSNu", gersNu_);
      Parameters::get(name + "->GERSThetaC", gersThetaC_);
326
327
    }

328
    Flag markGrid(AdaptInfo& adaptInfo) override;
329
330
331

  protected:
    /// Refinement marking function.
332
    void markElementForRefinement(AdaptInfo& adaptInfo, Element const& elem);
333
334

    /// Coarsening marking function.
335
    void markElementForCoarsening(AdaptInfo& adaptInfo, Element const& elem);
336
337
338

  protected:
    /// Marking parameter.
339
    double gersSum_ = 0.0;
340
341

    /// Marking parameter.
342
    double oldErrSum_ = 0.0;
343
344

    /// Marking parameter.
345
    double gersThetaStar_ = 0.6;
346
347

    /// Marking parameter.
348
    double gersNu_ = 0.1;
349
350

    /// Marking parameter.
351
    double gersThetaC_ = 0.1;
352
353
  };

Praetorius, Simon's avatar
Praetorius, Simon committed
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383

  /**
   * \ingroup Adaption
   *
   * \brief
   * Marker based on an indicator given as grid-function.
   *
   * On each element the grid-function is evaluated in the barycenter. The returned
   * values must be an integer (or convertible to an integer) indicating the
   * desired refinement level of this element. The element is marked for refinement
   * if the current level is < the desired level or coarsened, if >.
   *
   * \tparam Grid     An Implementation of the \ref Dune::Grid interface
   * \tparam GridFct  A grid-function with `Range` convertible to `int`
   */
  template <class Grid, class GridFct>
  class GridFunctionMarker
      : public Marker<Grid>
  {
    using Super = Marker<Grid>;
    using Element = typename Super::Element;

    template <class GF>
    using IsGridFunction = decltype(localFunction(std::declval<GF>()));

    static_assert(Dune::Std::is_detected<IsGridFunction,GridFct>::value, "");

  public:
    /// Constructor.
    template <class GF>
384
    GridFunctionMarker(std::string const& name, std::shared_ptr<Grid> const& grid, GF&& gf)
Praetorius, Simon's avatar
Praetorius, Simon committed
385
      : Super{name, grid}
386
      , gridFct_{makeGridFunction(FWD(gf), grid->leafGridView())}
387
    {}
Praetorius, Simon's avatar
Praetorius, Simon committed
388
389
390

    /// \brief Implementation of \ref Marker::markElement. Does nothing since marking is
    /// done in \ref markGrid().
391
    void markElement(AdaptInfo& adaptInfo, Element const& elem) final {}
Praetorius, Simon's avatar
Praetorius, Simon committed
392
393
394
395

    /// Mark element for refinement, if grid-function \ref gridFct_ evaluates to
    /// a value larger than the current level and is marked for coarsening of
    /// the result is less than the current value.
396
    Flag markGrid(AdaptInfo& adaptInfo) override;
Praetorius, Simon's avatar
Praetorius, Simon committed
397
398
399
400
401
402

  private:
    /// Indicator function for adaptation
    GridFct gridFct_;
  };

Praetorius, Simon's avatar
Praetorius, Simon committed
403

Praetorius, Simon's avatar
Praetorius, Simon committed
404
405
#if DUNE_HAVE_CXX_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
  // Deduction guide for GridFunctionMarker class
406
407
  template <class Grid, class GF>
  GridFunctionMarker(std::string const& name, std::shared_ptr<Grid> const& grid, GF&& gf)
Praetorius, Simon's avatar
Praetorius, Simon committed
408
    -> GridFunctionMarker<Grid,
409
          TYPEOF( makeGridFunction(FWD(gf), grid->leafGridView()) )>;
Praetorius, Simon's avatar
Praetorius, Simon committed
410
411
412
413
414
#endif

  // Generator function for GridFunctionMarker class
  template <class Grid, class PreGridFct>
  auto makeGridFunctionMarker(std::string const& name, std::shared_ptr<Grid> const& grid,
415
                              PreGridFct&& preGridFct)
Praetorius, Simon's avatar
Praetorius, Simon committed
416
  {
417
418
    auto gridFct = makeGridFunction(FWD(preGridFct), grid->leafGridView());
    return GridFunctionMarker<Grid,TYPEOF(gridFct)>{name, grid, std::move(gridFct)};
Praetorius, Simon's avatar
Praetorius, Simon committed
419
420
421
  }

} // end namespace AMDiS
422

423
#include "Marker.inc.hpp"