grid.hh 19.7 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>
17
#include <dune/functions/common/functionconcepts.hh>
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
18
19
20
21
22
23
#include <dune/grid/geometrygrid/identity.hh>
#include <dune/grid/geometrygrid/persistentcontainer.hh>
#include <dune/grid/geometrygrid/grid.hh>

namespace Dune
{
24
25
26
27
28
  namespace Impl
  {
    template< class GridFunction, int order >
    struct CurvedSurfaceGridBase
    {
29
      using HG = GridOf_t<GridFunction>;
30
31
32
33
34
35
36
37
38
39
40

      using type = GridDefaultImplementation<
        HG::dimension, CGeo::DimRange<GridFunction>::value, typename HG::ctype,
        CGeo::GridFamily<GridFunction,order>
      >;
    };
  }

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

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

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

  /** \class CurvedSurfaceGrid
   *  \brief grid wrapper replacing the geometries
Praetorius, Simon's avatar
Praetorius, Simon committed
47
   *  \ingroup CurvedGeo
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
48
   *
Praetorius, Simon's avatar
Praetorius, Simon committed
49
50
   *  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
51
   *
52
   *  \tparam GF     GridViewFunction defined on a (flat) hostgrid
53
   *  \tparam ORDER  Polynomial order of local lagrange basis functions to use when approximating
54
   *                 the curved geometry. [optional]
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
55
56
57
   *
   *  \nosubgrouping
   */
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  template< class GF, int ORDER = -1 >
  class CurvedSurfaceGrid;

  //! Generator for CurvedSurfaceGrid from a grid-functions
  template< class HostGrid, class GF, int ORDER = -1, 
    std::enable_if_t<Dune::Concept::isGridFunction<GF, HostGrid>(), int> = 0>
  auto curedSurfaceGrid (HostGrid& hostGrid, GF&& gridFunction) 
  {
    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
  template< class HostGrid, class F, int ORDER = -1, 
    std::enable_if_t<not Dune::Concept::isGridFunction<F, HostGrid>(), int> = 0>
  auto curedSurfaceGrid (HostGrid& hostGrid, F&& callable) 
  {
    using GlobalCoordinate = typename GridEntitySet<HostGrid,0>::GlobalCoordinate;
    static_assert(Functions::Concept::isCallable<F, GlobalCoordinate>(), "Function must be callable");
    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
83
  class CurvedSurfaceGrid
84
85
      : public CurvedSurfaceGridBase<GF,ORDER>
      , public CGeo::BackupRestoreFacilities<CurvedSurfaceGrid<GF,ORDER> >
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
86
  {
Praetorius, Simon's avatar
Praetorius, Simon committed
87
    using Self = CurvedSurfaceGrid;
88
    using Super = CurvedSurfaceGridBase<GF,ORDER>;
Praetorius, Simon's avatar
Praetorius, Simon committed
89
90
91
92

    // friend declarations
    template< class, class > friend class CGeo::IdSet;
    template< class, class > friend class CGeo::IndexSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
93
94

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

    /** \name Traits
     *  \{ */

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

104
105
    using HostGrid = typename Traits::HostGrid;

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

    /** \} */

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

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

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

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

    /** \} */

Praetorius, Simon's avatar
Praetorius, Simon committed
131

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

Praetorius, Simon's avatar
Praetorius, Simon committed
135
136
137
138
139
    //! 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

    /** \} */


    /** \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
155
    using LeafIndexSet = typename Traits::LeafIndexSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
156
157
158
159
160
161
162
163
164

    /** \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
165
    using LevelIndexSet = typename Traits::LevelIndexSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
166
167
168
169
170
171
172
173
174
175
176

    /** \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
177
    using GlobalIdSet = typename Traits::GlobalIdSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

    /** \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
194
    using LocalIdSet = typename Traits::LocalIdSet;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
195
196
197
198
199
200
201

    /** \} */

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

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

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

    /** \} */

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

Praetorius, Simon's avatar
Praetorius, Simon committed
212
213
214
    //! constructor for host-grid given by reference
    /**
     *  The references to host grid is stored in the grid. It must be valid until this grid
215
     *  wrapper is destroyed.
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
216
     *
217
218
219
220
221
222
     *  \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
     * 
     *  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
223
     */
224
225
226
    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> = {})
227
      : hostGrid_(hostGrid)
228
      , gridFunction_(wrap_or_move(std::forward<GF_>(gridFunction)))
229
      , levelIndexSets_(hostGrid_.maxLevel()+1, nullptr)
Praetorius, Simon's avatar
Praetorius, Simon committed
230
    {}
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
231

232
233
234
235
236
    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
237

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

    /** \} */

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

Praetorius, Simon's avatar
Praetorius, Simon committed
253
254
    //! obtain maximal grid level
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
255
256
257
258
259
260
261
262
263
264
     *  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
265
266
    //! obtain number of entites on a level
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
267
268
269
     *  \param[in]  level  level to consider
     *  \param[in]  codim  codimension to consider
     *
Praetorius, Simon's avatar
Praetorius, Simon committed
270
     *  \returns number of entities of codimension `codim` on grid level `level`.
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
271
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
272
    int size (int level, int codim) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
273
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
274
      return levelGridView(level).size(codim);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
275
276
    }

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

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

Praetorius, Simon's avatar
Praetorius, Simon committed
300
301
302
    //! 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
303
     */
Praetorius, Simon's avatar
Praetorius, Simon committed
304
    int size (GeometryType type) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
305
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
306
      return leafGridView().size(type);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
307
308
    }

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

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

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

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

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

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

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

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

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

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

    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
393
394
    //! obtain CollectiveCommunication object
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
395
396
397
398
399
400
     *  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
401
    const CollectiveCommunication& comm () const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
402
403
404
405
406
407
    {
      return hostGrid().comm();
    }

    // data handle interface different between geo and interface

Praetorius, Simon's avatar
Praetorius, Simon committed
408
409
    //! rebalance the load each process has to handle
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
410
411
412
413
414
415
416
417
418
     *  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
419
420
      const bool gridChanged = hostGrid().loadBalance();
      if (gridChanged)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
421
422
423
424
        update();
      return gridChanged;
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
425
426
    //! rebalance the load each process has to handle
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
427
428
429
430
431
432
433
434
435
436
437
438
439
440
     *  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
441
    bool loadBalance (CommDataHandleIF<DataHandle, Data>& datahandle)
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
442
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
443
      using DataHandleIF = CommDataHandleIF<DataHandle, Data>;
444
      using WrappedDataHandle = CGeo::CommDataHandle<Self, DataHandleIF>;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
445

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

Praetorius, Simon's avatar
Praetorius, Simon committed
453
454
    //! obtain Entity from EntitySeed
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
455
     *  EntitySeed survives to a grid modification which only changes the grid coordinates.
Praetorius, Simon's avatar
Praetorius, Simon committed
456
457
     *  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
458
459
     */
    template< class EntitySeed >
Praetorius, Simon's avatar
Praetorius, Simon committed
460
    typename Traits::template Codim<EntitySeed::codimension>::Entity entity (const EntitySeed& seed) const
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
461
    {
Praetorius, Simon's avatar
Praetorius, Simon committed
462
463
      using EntityImpl = typename Traits::template Codim<EntitySeed::codimension>::EntityImpl;
      return EntityImpl(*this, seed);
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
464
465
466
467
468
469
470
    }

    /** \} */

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

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

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

    /** \} */

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

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

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

Praetorius, Simon's avatar
Praetorius, Simon committed
502
503
    //! update grid caches
    /**
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
504
505
506
507
508
509
510
511
512
     *  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
513
      // GeoGrid::AdaptCoordFunction<typename CoordFunction::Interface>::adapt(coordFunction());
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
514
515
516
517

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

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

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

    GridFunction& gridFunction () 
    { 
      return *gridFunction_; 
    }
536
537
538
539
540
541
542
543
544
545

    bool useGeometryCaching () const
    {
      return useGeometryCaching_;
    }

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

    /** \} */

  protected:
    template< int codim >
Praetorius, Simon's avatar
Praetorius, Simon committed
551
552
    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
553
    {
554
      return entity.impl().hostEntity();
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
555
556
557
    }

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

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

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

Praetorius, Simon's avatar
Praetorius, Simon committed
568
569
570
571
572
573
574
575
576
577
  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,
578
          typename Traits::template Codim<codims>::GeometryImpl
Praetorius, Simon's avatar
Praetorius, Simon committed
579
580
581
582
        >...
      >;
    };

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

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

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

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

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

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

    /** \} */

    /** \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.
     */
622
    using Geometry = typename Traits::template Codim< codim >::Geometry;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
623
624
625
626
627
628
629
630
631

    /** \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.
     */
632
    using LocalGeometry = typename Traits::template Codim< codim >::LocalGeometry;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
633
634
635
636
637
638
639
640
641

    /** \} */

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

    template< PartitionIteratorType pitype >
    struct Partition
    {
642
643
644
645
      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
646
647
648
649
650
651
652
653
654
    };

    /** \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.
     */
655
    using LeafIterator = typename Partition< All_Partition >::LeafIterator;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
656
657
658
659
660
661
662
663

    /** \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.
     */
664
    using LevelIterator = typename Partition< All_Partition >::LevelIterator;
Stenger, Florian's avatar
v0.1.0  
Stenger, Florian committed
665
666
667
668
669
670

    /** \} */
  };

} // namespace Dune

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