grid.hh 19.6 KB
Newer Older
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
1
2
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
Praetorius, Simon's avatar
Praetorius, Simon committed
3
4
#ifndef DUNE_CURVED_SURFACE_GRID_GRID_HH
#define DUNE_CURVED_SURFACE_GRID_GRID_HH
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
5
6

#include <dune/common/deprecated.hh>
7
#include <dune/common/shared_ptr.hh>
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
8
9
10

#include <dune/grid/common/grid.hh>

11
#include <dune/curvedsurfacegrid/concepts.hh>
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
12
13
14
#include <dune/curvedsurfacegrid/gridfamily.hh>
#include <dune/curvedsurfacegrid/backuprestore.hh>
#include <dune/curvedsurfacegrid/datahandle.hh>
15
#include <dune/curvedsurfacegrid/gridfunctions/analyticgridfunction.hh>
16
#include <dune/curvedsurfacegrid/gridfunctions/gridfunction.hh>
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
17
18
19
20
21
22
#include <dune/grid/geometrygrid/identity.hh>
#include <dune/grid/geometrygrid/persistentcontainer.hh>
#include <dune/grid/geometrygrid/grid.hh>

namespace Dune
{
23
24
25
26
27
  namespace Impl
  {
    template< class GridFunction, int order >
    struct CurvedSurfaceGridBase
    {
28
      using HG = GridOf_t<GridFunction>;
29
30

      using type = GridDefaultImplementation<
31
32
        HG::dimension, Curved::DimRange<GridFunction>::value, typename HG::ctype,
        Curved::GridFamily<GridFunction,order>
33
34
35
36
37
38
39
      >;
    };
  }

  template< class GridFunction, int order >
  using CurvedSurfaceGridBase = typename Impl::CurvedSurfaceGridBase<GridFunction,order>::type;

Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
40
41
42
43
44
45

  // CurvedSurfaceGrid
  // -----------------

  /** \class CurvedSurfaceGrid
   *  \brief grid wrapper replacing the geometries
Praetorius, Simon's avatar
Praetorius, Simon committed
46
   *  \ingroup CurvedGeo
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
47
   *
Praetorius, Simon's avatar
Praetorius, Simon committed
48
49
   *  CurvedSurfaceGrid wraps another DUNE grid and replaces its geometry by an implementation
   *  of a CurvedGeometry.
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
50
   *
51
   *  \tparam GF     GridViewFunction defined on a (flat) hostgrid
52
   *  \tparam ORDER  Polynomial order of local lagrange basis functions to use when approximating
53
   *                 the curved geometry. [optional]
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
54
55
56
   *
   *  \nosubgrouping
   */
57
58
59
60
  template< class GF, int ORDER = -1 >
  class CurvedSurfaceGrid;

  //! Generator for CurvedSurfaceGrid from a grid-functions
61
62
63
  template< class HostGrid, class GF, int ORDER = -1,
    std::enable_if_t<Concept::isGridFunction<GF, HostGrid>(), int> = 0>
  auto curedSurfaceGrid (HostGrid& hostGrid, GF&& gridFunction)
64
65
66
67
68
69
  {
    static_assert(std::is_same<HostGrid, GridOf_t<std::decay_t<GF>>>::value, "GridFunction must be defined on the HostGrid");
    return CurvedSurfaceGrid<std::decay_t<GF>,ORDER>{hostGrid, std::forward<GF>(gridFunction)};
  }

  //! Generator for CurvedSurfaceGrid from a callable
70
71
72
  template< class HostGrid, class F, int ORDER = -1,
    std::enable_if_t<not Concept::isGridFunction<F, HostGrid>(), int> = 0>
  auto curedSurfaceGrid (HostGrid& hostGrid, F&& callable)
73
74
  {
    using GlobalCoordinate = typename GridEntitySet<HostGrid,0>::GlobalCoordinate;
75
    static_assert(Concept::isCallable<F, GlobalCoordinate>(), "Function must be callable");
76
77
78
79
80
81
    auto gridFct = analyticGridFunction<HostGrid>(std::forward<F>(callable));
    return CurvedSurfaceGrid<decltype(gridFct),ORDER>{hostGrid, std::move(gridFct)};
  }


  template< class GF, int ORDER >
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
82
  class CurvedSurfaceGrid
83
      : public CurvedSurfaceGridBase<GF,ORDER>
84
      , public Curved::BackupRestoreFacilities<CurvedSurfaceGrid<GF,ORDER> >
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
85
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
86
    using Self = CurvedSurfaceGrid;
87
    using Super = CurvedSurfaceGridBase<GF,ORDER>;
Praetorius, Simon's avatar
Praetorius, Simon committed
88
89

    // friend declarations
90
91
    template< class, class > friend class Curved::IdSet;
    template< class, class > friend class Curved::IndexSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
92
93

  public:
94
    using GridFunction = GF;
95
    using GridFamily = Curved::GridFamily<GF,ORDER>;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
96
97
98
99
100

    /** \name Traits
     *  \{ */

    //! type of the grid traits
Praetorius, Simon's avatar
Praetorius, Simon committed
101
    using Traits = typename GridFamily::Traits;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
102

103
104
    using HostGrid = typename Traits::HostGrid;

Praetorius, Simon's avatar
Praetorius, Simon committed
105
106
    //! traits structure containing types for a codimension
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
107
108
109
110
111
112
113
114
115
116
117
118
119
     *  \tparam codim  codimension
     *
     *  \nosubgrouping
     */
    template< int codim >
    struct Codim;

    /** \} */

    /** \name Iterator Types
     *  \{ */

    //! iterator over the grid hierarchy
Praetorius, Simon's avatar
Praetorius, Simon committed
120
121
    using HierarchicIterator = typename Traits::HierarchicIterator;

Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
122
    //! iterator over intersections with other entities on the leaf level
Praetorius, Simon's avatar
Praetorius, Simon committed
123
124
    using LeafIntersectionIterator = typename Traits::LeafIntersectionIterator;

Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
125
    //! iterator over intersections with other entities on the same level
Praetorius, Simon's avatar
Praetorius, Simon committed
126
    using LevelIntersectionIterator = typename Traits::LevelIntersectionIterator;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
127
128
129

    /** \} */

Praetorius, Simon's avatar
Praetorius, Simon committed
130

Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
131
132
133
    /** \name Grid View Types
     *  \{ */

Praetorius, Simon's avatar
Praetorius, Simon committed
134
135
136
137
138
    //! type of view for leaf grid
    using LeafGridView = typename GridFamily::Traits::LeafGridView;

    //! type of view for level grid
    using LevelGridView = typename GridFamily::Traits::LevelGridView;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

    /** \} */


    /** \name Index and Id Set Types
     *  \{ */

    /** \brief type of leaf index set
     *
     *  The index set assigns consecutive indices to the entities of the
     *  leaf grid. The indices are of integral type and can be used to access
     *  arrays.
     *
     *  The leaf index set is a model of Dune::IndexSet.
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
154
    using LeafIndexSet = typename Traits::LeafIndexSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
155
156
157
158
159
160
161
162
163

    /** \brief type of level index set
     *
     *  The index set assigns consecutive indices to the entities of a grid
     *  level. The indices are of integral type and can be used to access
     *  arrays.
     *
     *  The level index set is a model of Dune::IndexSet.
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
164
    using LevelIndexSet = typename Traits::LevelIndexSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
165
166
167
168
169
170
171
172
173
174
175

    /** \brief type of global id set
     *
     *  The id set assigns a unique identifier to each entity within the
     *  grid. This identifier is unique over all processes sharing this grid.
     *
     *  \note Id's are neither consecutive nor necessarily of an integral
     *        type.
     *
     *  The global id set is a model of Dune::IdSet.
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
176
    using GlobalIdSet = typename Traits::GlobalIdSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192

    /** \brief type of local id set
     *
     *  The id set assigns a unique identifier to each entity within the
     *  grid. This identifier needs only to be unique over this process.
     *
     *  Though the local id set may be identical to the global id set, it is
     *  often implemented more efficiently.
     *
     *  \note Ids are neither consecutive nor necessarily of an integral
     *        type.
     *  \note Local ids need not be compatible with global ids. Also, no
     *        mapping from local ids to global ones needs to exist.
     *
     *  The global id set is a model of Dune::IdSet.
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
193
    using LocalIdSet = typename Traits::LocalIdSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
194
195
196
197
198
199
200

    /** \} */

    /** \name Miscellaneous Types
     * \{ */

    //! type of vector coordinates (e.g., double)
Praetorius, Simon's avatar
Praetorius, Simon committed
201
    using ctype = typename Traits::ctype;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
202
203

    //! communicator with all other processes having some part of the grid
Praetorius, Simon's avatar
Praetorius, Simon committed
204
    using CollectiveCommunication = typename Traits::CollectiveCommunication;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
205
206
207
208
209
210

    /** \} */

    /** \name Construction and Destruction
     *  \{ */

Praetorius, Simon's avatar
Praetorius, Simon committed
211
212
213
    //! constructor for host-grid given by reference
    /**
     *  The references to host grid is stored in the grid. It must be valid until this grid
214
     *  wrapper is destroyed.
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
215
     *
216
217
218
     *  \param[in]  hostGrid      reference to the grid to wrap
     *  \param[in]  gridFunction  mapping from global coordinates in the host geometry
     *                            to global coordinates in the curved geometry
219
     *
220
221
     *  If the gridFunction is passed by (non-const) reference it is stored as a non-destroying shared_ptr.
     *  Otherwise it is copied or moved into a new object (stored as shared_ptr as well).
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
222
     */
223
224
225
    template <class GF_,
      std::enable_if_t<std::is_same<GF,std::decay_t<GF_>>::value, int> = 0>
    CurvedSurfaceGrid (HostGrid& hostGrid, GF_&& gridFunction, std::integral_constant<int,ORDER> = {})
226
      : hostGrid_(hostGrid)
227
      , gridFunction_(wrap_or_move(std::forward<GF_>(gridFunction)))
228
      , levelIndexSets_(hostGrid_.maxLevel()+1, nullptr)
Praetorius, Simon's avatar
Praetorius, Simon committed
229
    {}
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
230

231
232
233
234
235
    template <class F_,
      std::enable_if_t<std::is_same<GF,AnalyticGridFunction<HostGrid,std::decay_t<F_>>>::value, int> = 0>
    CurvedSurfaceGrid (HostGrid& hostGrid, F_&& callable, std::integral_constant<int,ORDER> = {})
      : CurvedSurfaceGrid(hostGrid, analyticGridFunction<HostGrid>(std::forward<F_>(callable)))
    {}
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
236

Praetorius, Simon's avatar
Praetorius, Simon committed
237
    //! destructor
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
238
239
    ~CurvedSurfaceGrid ()
    {
240
      for (unsigned int i = 0; i < levelIndexSets_.size(); ++i)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
241
      {
242
243
        if (levelIndexSets_[i])
          delete (levelIndexSets_[i]);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
244
245
246
247
248
249
250
251
      }
    }

    /** \} */

    /** \name Size Methods
     *  \{ */

Praetorius, Simon's avatar
Praetorius, Simon committed
252
253
    //! obtain maximal grid level
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
254
255
256
257
258
259
260
261
262
263
     *  Grid levels are numbered 0, ..., L, where L is the value returned by
     *  this method.
     *
     *  \returns maximal grid level
     */
    int maxLevel () const
    {
      return hostGrid().maxLevel();
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
264
265
    //! obtain number of entites on a level
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
266
267
268
     *  \param[in]  level  level to consider
     *  \param[in]  codim  codimension to consider
     *
Praetorius, Simon's avatar
Praetorius, Simon committed
269
     *  \returns number of entities of codimension `codim` on grid level `level`.
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
270
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
271
    int size (int level, int codim) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
272
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
273
      return levelGridView(level).size(codim);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
274
275
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
276
277
    //! obtain number of leaf entities
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
278
279
280
281
     *  \param[in]  codim  codimension to consider
     *
     *  \returns number of leaf entities of codimension \em codim
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
282
    int size (int codim) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
283
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
284
      return leafGridView().size(codim);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
285
286
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
287
288
    //! obtain number of entites on a level
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
289
290
291
     *  \param[in]  level  level to consider
     *  \param[in]  type   geometry type to consider
     *
Praetorius, Simon's avatar
Praetorius, Simon committed
292
     *  \returns number of entities with a geometry of type `type` on grid level `level`.
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
293
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
294
    int size (int level, GeometryType type) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
295
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
296
      return levelGridView(level).size(type);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
297
298
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
299
300
301
    //! obtain number of leaf entities
    /**
     *  \returns number of leaf entities with a geometry of type `type`
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
302
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
303
    int size (GeometryType type) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
304
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
305
      return leafGridView().size(type);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
306
307
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
308
309
    //! returns the number of boundary segments within the macro grid
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
310
311
     *  \returns number of boundary segments within the macro grid
     */
312
    std::size_t numBoundarySegments () const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
313
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
314
      return hostGrid().numBoundarySegments();
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
315
316
317
    }
    /** \} */

Praetorius, Simon's avatar
Praetorius, Simon committed
318
    const GlobalIdSet& globalIdSet () const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
319
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
320
321
322
      if (!globalIdSet_)
        globalIdSet_ = GlobalIdSet(hostGrid().globalIdSet());
      assert(globalIdSet_);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
323
324
325
      return globalIdSet_;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
326
    const LocalIdSet& localIdSet () const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
327
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
328
329
330
      if (!localIdSet_)
        localIdSet_ = LocalIdSet(hostGrid().localIdSet());
      assert(localIdSet_);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
331
332
333
      return localIdSet_;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
334
    const LevelIndexSet& levelIndexSet (int level) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
335
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
336
      assert(levelIndexSets_.size() == (size_t)(maxLevel()+1));
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
337

Praetorius, Simon's avatar
Praetorius, Simon committed
338
339
      if ((level < 0) || (level > maxLevel()))
        DUNE_THROW(GridError, "LevelIndexSet for nonexisting level " << level << " requested.");
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
340

Praetorius, Simon's avatar
Praetorius, Simon committed
341
342
343
344
      LevelIndexSet*& levelIndexSet = levelIndexSets_[level];
      if (!levelIndexSet)
        levelIndexSet = new LevelIndexSet(hostGrid().levelIndexSet(level));
      assert(levelIndexSet);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
345
346
347
      return *levelIndexSet;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
348
    const LeafIndexSet& leafIndexSet () const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
349
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
350
351
352
      if (!leafIndexSet_)
        leafIndexSet_.reset(hostGrid().leafIndexSet());
      assert(leafIndexSet_);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
353
354
355
      return leafIndexSet_;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
356
    void globalRefine (int refCount)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
357
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
358
      hostGrid().globalRefine(refCount);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
359
360
361
      update();
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
362
    bool mark (int refCount, const typename Codim<0>::Entity& entity)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
363
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
364
      return hostGrid().mark(refCount, getHostEntity<0>(entity));
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
365
366
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
367
    int getMark (const typename Codim<0>::Entity& entity) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
368
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
369
      return hostGrid().getMark(getHostEntity<0>(entity));
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
    }

    bool preAdapt ()
    {
      return hostGrid().preAdapt();
    }

    bool adapt ()
    {
      bool ret = hostGrid().adapt();
      update();
      return ret;
    }

    void postAdapt ()
    {
      hostGrid().postAdapt();
    }

    /** \name Parallel Data Distribution and Communication Methods
     *  \{ */

Praetorius, Simon's avatar
Praetorius, Simon committed
392
393
    //! obtain CollectiveCommunication object
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
394
395
396
397
398
399
     *  The CollectiveCommunication object should be used to globally
     *  communicate information between all processes sharing this grid.
     *
     *  \note The CollectiveCommunication object returned is identical to the
     *        one returned by the host grid.
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
400
    const CollectiveCommunication& comm () const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
401
402
403
404
405
406
    {
      return hostGrid().comm();
    }

    // data handle interface different between geo and interface

Praetorius, Simon's avatar
Praetorius, Simon committed
407
408
    //! rebalance the load each process has to handle
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
409
410
411
412
413
414
415
416
417
     *  A parallel grid is redistributed such that each process has about
     *  the same load (e.g., the same number of leaf entites).
     *
     *  \note DUNE does not specify, how the load is measured.
     *
     *  \returns \b true, if the grid has changed.
     */
    bool loadBalance ()
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
418
419
      const bool gridChanged = hostGrid().loadBalance();
      if (gridChanged)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
420
421
422
423
        update();
      return gridChanged;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
424
425
    //! rebalance the load each process has to handle
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
426
427
428
429
430
431
432
433
434
435
436
437
438
439
     *  A parallel grid is redistributed such that each process has about
     *  the same load (e.g., the same number of leaf entites).
     *
     *  The data handle is used to communicate the data associated with
     *  entities that move from one process to another.
     *
     *  \note DUNE does not specify, how the load is measured.
     *
     *  \param  datahandle  communication data handle (user defined)
     *
     *  \returns \b true, if the grid has changed.
     */

    template< class DataHandle, class Data >
Praetorius, Simon's avatar
Praetorius, Simon committed
440
    bool loadBalance (CommDataHandleIF<DataHandle, Data>& datahandle)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
441
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
442
      using DataHandleIF = CommDataHandleIF<DataHandle, Data>;
443
      using WrappedDataHandle = Curved::CommDataHandle<Self, DataHandleIF>;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
444

Praetorius, Simon's avatar
Praetorius, Simon committed
445
446
447
      WrappedDataHandle wrappedDataHandle(*this, datahandle);
      const bool gridChanged = hostGrid().loadBalance(wrappedDataHandle);
      if (gridChanged)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
448
449
450
451
        update();
      return gridChanged;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
452
453
    //! obtain Entity from EntitySeed
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
454
     *  EntitySeed survives to a grid modification which only changes the grid coordinates.
Praetorius, Simon's avatar
Praetorius, Simon committed
455
456
     *  Therefore it is consistent to use an EntitySeed to rebuild an Entity after this kind
     *  of grid modification.
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
457
458
     */
    template< class EntitySeed >
Praetorius, Simon's avatar
Praetorius, Simon committed
459
    typename Traits::template Codim<EntitySeed::codimension>::Entity entity (const EntitySeed& seed) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
460
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
461
462
      using EntityImpl = typename Traits::template Codim<EntitySeed::codimension>::EntityImpl;
      return EntityImpl(*this, seed);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
463
464
465
466
467
468
469
    }

    /** \} */

    /** \name Grid Views
     *  \{ */

Praetorius, Simon's avatar
Praetorius, Simon committed
470
471
    //! View for a grid level
    LevelGridView levelGridView (int level) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
472
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
473
474
      using ViewImp = typename LevelGridView::GridViewImp;
      return LevelGridView(ViewImp(*this, hostGrid().levelGridView(level)));
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
475
476
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
477
    //! View for the leaf grid
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
478
479
    LeafGridView leafGridView () const
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
480
481
      using ViewImp = typename LeafGridView::GridViewImp;
      return LeafGridView(ViewImp(*this, hostGrid().leafGridView()));
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
482
483
484
485
486
487
488
    }

    /** \} */

    /** \name Miscellaneous Methods
     *  \{ */

Praetorius, Simon's avatar
Praetorius, Simon committed
489
490
    //! obtain constant reference to the host grid
    const HostGrid& hostGrid () const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
491
    {
492
      return hostGrid_;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
493
494
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
495
496
    //! obtain mutable reference to the host grid
    HostGrid& hostGrid ()
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
497
    {
498
      return hostGrid_;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
499
500
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
501
502
    //! update grid caches
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
503
504
505
506
507
508
509
510
511
     *  This method has to be called whenever the underlying host grid changes.
     *
     *  \note If you adapt the host grid through this geometry grid's
     *        adaptation or load balancing methods, update is automatically
     *        called.
     */
    void update ()
    {
      // adapt the coordinate function
512
      // GeoGrid::AdaptCoordFunction<typename CoordFunction::Interface>::adapt(coordFunction());
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
513
514
515
516

      const int newNumLevels = maxLevel()+1;
      const int oldNumLevels = levelIndexSets_.size();

Praetorius, Simon's avatar
Praetorius, Simon committed
517
      for (int i = newNumLevels; i < oldNumLevels; ++i)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
518
      {
Praetorius, Simon's avatar
Praetorius, Simon committed
519
520
        if (levelIndexSets_[i])
          delete levelIndexSets_[i];
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
521
      }
Praetorius, Simon's avatar
Praetorius, Simon committed
522
      levelIndexSets_.resize(newNumLevels, nullptr);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
523
524
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
525
    //! obtain constant reference to the coordinate function
526
527
528
    GridFunction const& gridFunction () const
    {
      return *gridFunction_;
529
530
    }

531
532
533
    GridFunction& gridFunction ()
    {
      return *gridFunction_;
534
    }
535
536
537
538
539
540
541
542
543
544

    bool useGeometryCaching () const
    {
      return useGeometryCaching_;
    }

    void setGeometryCaching (bool cache)
    {
      useGeometryCaching_ = cache;
    }
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
545
546
547
548
549

    /** \} */

  protected:
    template< int codim >
Praetorius, Simon's avatar
Praetorius, Simon committed
550
551
    static const typename HostGrid::template Codim<codim>::Entity&
    getHostEntity(const typename Codim<codim>::Entity& entity)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
552
    {
553
      return entity.impl().hostEntity();
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
554
555
556
    }

  private:
557
    HostGrid& hostGrid_;
558
    std::shared_ptr<GridFunction> gridFunction_;
Praetorius, Simon's avatar
Praetorius, Simon committed
559

560
    bool useGeometryCaching_ = false;
Praetorius, Simon's avatar
Praetorius, Simon committed
561

562
    mutable std::vector<LevelIndexSet*> levelIndexSets_;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
563
564
565
566
    mutable LeafIndexSet leafIndexSet_;
    mutable GlobalIdSet globalIdSet_;
    mutable LocalIdSet localIdSet_;

Praetorius, Simon's avatar
Praetorius, Simon committed
567
568
569
570
571
572
573
574
575
576
  private:
    template <class Indices>
    struct GeometryCache;

    template <int... codims>
    struct GeometryCache<std::integer_sequence<int,codims...>>
    {
      using type = std::tuple<
        std::map<
          typename HostGrid::Traits::LocalIdSet::IdType,
577
          typename Traits::template Codim<codims>::GeometryImpl
Praetorius, Simon's avatar
Praetorius, Simon committed
578
579
580
581
        >...
      >;
    };

582
    mutable typename GeometryCache<std::make_integer_sequence<int,Traits::dimension+1>>::type geometryCache_;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
583
584
  };

585
586
  //! Deduction guide for CurvedSurfaceGrid from a grid-functions or callables
  template< class HostGrid, class GF, int ORDER = -1 >
587
  CurvedSurfaceGrid (HostGrid& hostGrid, GF&& gridFunction, std::integral_constant<int,ORDER> = {})
588
589
    -> CurvedSurfaceGrid<GridFunctionOf_t<HostGrid,std::decay_t<GF>>,ORDER>;

Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
590
591
592
593

  // CurvedSurfaceGrid::Codim
  // ------------------------

594
  template< class GridFunction, int ORDER >
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
595
  template< int codim >
596
  struct CurvedSurfaceGrid<GridFunction,ORDER>::Codim
597
    : public Super::template Codim< codim >
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
598
599
600
601
602
603
604
605
  {
    /** \name Entity types
     *  \{ */

    /** \brief type of entity
     *
     *  The entity is a model of Dune::Entity.
     */
606
    using Entity = typename Traits::template Codim< codim >::Entity;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
607
608
609
610
611
612
613
614
615
616
617
618
619
620

    /** \} */

    /** \name Geometry Types
     *  \{ */

    /** \brief type of world geometry
     *
     *  Models the geomtry mapping of the entity, i.e., the mapping from the
     *  reference element into world coordinates.
     *
     *  The geometry is a model of Dune::Geometry, implemented through the
     *  generic geometries provided by dune-grid.
     */
621
    using Geometry = typename Traits::template Codim< codim >::Geometry;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
622
623
624
625
626
627
628
629
630

    /** \brief type of local geometry
     *
     *  Models the geomtry mapping into the reference element of dimension
     *  \em dimension.
     *
     *  The local geometry is a model of Dune::Geometry, implemented through
     *  the generic geometries provided by dune-grid.
     */
631
    using LocalGeometry = typename Traits::template Codim< codim >::LocalGeometry;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
632
633
634
635
636
637
638
639
640

    /** \} */

    /** \name Iterator Types
     *  \{ */

    template< PartitionIteratorType pitype >
    struct Partition
    {
641
642
643
644
      using LeafIterator
        = typename Traits::template Codim<codim>::template Partition< pitype >::LeafIterator;
      using LevelIterator
        = typename Traits::template Codim<codim>::template Partition< pitype >::LevelIterator;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
645
646
647
648
649
650
651
652
653
    };

    /** \brief type of leaf iterator
     *
     *  This iterator enumerates the entites of codimension \em codim of a
     *  grid level.
     *
     *  The level iterator is a model of Dune::LevelIterator.
     */
654
    using LeafIterator = typename Partition< All_Partition >::LeafIterator;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
655
656
657
658
659
660
661
662

    /** \brief type of level iterator
     *
     *  This iterator enumerates the entites of codimension \em codim of the
     *  leaf grid.
     *
     *  The leaf iterator is a model of Dune::LeafIterator.
     */
663
    using LevelIterator = typename Partition< All_Partition >::LevelIterator;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
664
665
666
667
668
669

    /** \} */
  };

} // namespace Dune

Praetorius, Simon's avatar
Praetorius, Simon committed
670
#endif // DUNE_CURVED_SURFACE_GRID_GRID_HH