entity.hh 12.2 KB
Newer Older
1
2
#ifndef DUNE_CURVEDSURFACEGRID_ENTITY_HH
#define DUNE_CURVEDSURFACEGRID_ENTITY_HH
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
3

Praetorius, Simon's avatar
Praetorius, Simon committed
4
5
#include <optional>

6
#include <dune/curvedsurfacegrid/geometry.hh>
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
7
8
9
#include <dune/geometry/referenceelements.hh>
#include <dune/grid/common/grid.hh>

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
namespace Dune {
namespace Curved {

// Internal Forward Declarations
// -----------------------------

/** \class EntityBase
 *  \brief actual implementation of the entity
 *  \ingroup CurvedGeo
 *
 *  \tparam  codim  codimension of the entity
 *  \tparam  Grid   CurvedSurfaceGrid, this entity belongs to
 */
template <int codim, class Grid>
class EntityBase;

/** \class Entity
 *  \brief DUNE-conform implementation of the entity
 *  \ingroup CurvedGeo
 *
 *  This class merely changes the template parameters of the entity to make
 *  DUNE happy. The actual implementation of the entity can be found in
 *  EntityBase.
 *
 *  \tparam  codim  codimension of the entity
 *  \tparam  dim    dimension of the Grid (redundant information)
 *  \tparam  Grid   CurvedSurfaceGrid, this entity belongs to
 */
template <int codim, int dim, class Grid>
class Entity;



// External Forward Declarations
// -----------------------------

template <class Grid>
class HierarchicIterator;

template <class Grid, class HostIntersectionIterator>
class IntersectionIterator;


template <int codim, class G>
class EntityBase
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
55
{
56
57
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
  using Traits = typename std::remove_const_t<G>::Traits;

public:
  /** \name Attributes
   *  \{ */

  /// \brief codimensioon of the entity
  static const int codimension = codim;
  /// \brief dimension of the grid
  static const int dimension = Traits::dimension;
  /// \brief dimension of the entity
  static const int mydimension = dimension - codimension;
  /// \brief dimension of the world
  static const int dimensionworld = Traits::dimensionworld;

  /** \} */

  /** \name Types Required by DUNE
   *  \{ */

  /// \brief coordinate type of the grid
  using ctype = typename Traits::ctype;

  /** \} */

public:
  /** \name Host Types
   *  \{ */

  /// \brief type of corresponding entity seed
  using EntitySeed = typename Traits::template Codim<codimension>::EntitySeed;

  /** \} */

public:
  using Grid = typename Traits::Grid;
  using GridFunction = typename Traits::GridFunction;

  /// \brief type of the host grid
  using HostGrid = typename Traits::HostGrid;

  /// \brief type of corresponding host entity
  using HostEntity = typename HostGrid::template Codim<codim>::Entity;

  /// \brief type of host elements, i.e., of host entities of codimension 0
  using HostElement = typename HostGrid::template Codim<0>::Entity;

public:
  EntityBase () = default;

  /// \brief Construct the entity from an entity seed
  EntityBase (const Grid& grid, const EntitySeed& seed)
    : hostEntity_(grid.hostGrid().entity(seed.impl().hostEntitySeed()))
    , gridFunction_(&grid.gridFunction())
  {}

  /// \brief construct the entity from a subentity of a host-entity
  EntityBase (const GridFunction& gridFunction, const HostElement& hostElement, int i)
    : hostEntity_(hostElement.template subEntity<codim>(i))
    , gridFunction_(&gridFunction)
  {}

  /// \brief construct the entity from a host-entity
  EntityBase (const GridFunction& gridFunction, const HostEntity& hostEntity)
    : hostEntity_(hostEntity)
    , gridFunction_(&gridFunction)
  {}

  /// \brief construct the entity from a host-entity
  EntityBase (const GridFunction& gridFunction, HostEntity&& hostEntity)
    : hostEntity_(std::move(hostEntity))
    , gridFunction_(&gridFunction)
  {}

  /// \brief compare two entities
  bool equals (const EntityBase& other) const
  {
    return hostEntity_ == other.hostEntity_;
  }

public:
  /** \name Methods Shared by Entities of All Codimensions
   *  \{ */

  /// \brief obtain the name of the corresponding reference element
  /**
   *  This type can be used to access the DUNE reference element.
   */
  GeometryType type () const
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
145
  {
146
147
    return hostEntity().type();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
148

149
150
151
152
153
  /// \brief obtain the level of this entity
  int level () const
  {
    return hostEntity().level();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
154

155
156
157
158
159
  /// \brief obtain the partition type of this entity
  PartitionType partitionType () const
  {
    return hostEntity().partitionType();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
160

161
162
163
164
165
  /// \brief obtain number of sub-entities of the current entity
  unsigned int subEntities (unsigned int cc) const
  {
    return hostEntity().subEntities(cc);
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
166

167
168
169
170
171
  /// \brief return EntitySeed of host grid entity
  EntitySeed seed () const
  {
    return typename EntitySeed::Implementation(hostEntity().seed());
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
172
173


174
175
  /** \name Methods Supporting the Grid Implementation
   *  \{ */
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
176

177
178
179
180
  const GridFunction& gridFunction () const
  {
    return *gridFunction_;
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
181

182
183
184
185
186
  /// \brief return the wrapped host-entity
  const HostEntity& hostEntity () const
  {
    return hostEntity_;
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
187

188
  /** \} */
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
private:
  HostEntity hostEntity_;
  const GridFunction* gridFunction_ = nullptr;
};


template <int codim, class G>
class EntityBaseGeometry
    : public EntityBase<codim, G>
{
  using Super = EntityBase<codim, G>;
  using Traits = typename std::remove_const_t<G>::Traits;

  /// \brief type of host elements, i.e., of host entities of codimension 0
  using HostElement = typename Traits::HostGrid::template Codim<0>::Entity;
  using GridFunction = typename Super::GridFunction;

public:
  /// \brief type of corresponding geometry
  using Geometry = typename Traits::template Codim<codim>::Geometry;
  using ctype = typename Geometry::ctype;

public:
  using Super::Super;

  /// \brief Construct the entity from a subentity of a host-entity
  EntityBaseGeometry (const GridFunction& gridFunction, const HostElement& hostElement, int i)
    : Super(gridFunction, hostElement, i)
    , hostElement_(hostElement)
    , subEntity_(i)
  {}

  /// \brief Obtain the geometry of this entity
  /**
   * The geometry can only be constructed of the entity is constructed as a sub-entity
   * of a grid elements. This is, because the geometry is parametrized by a local function
   * that must be bound to a grid element.
   *
   * NOTE: This only works if the grid is twist-free. Otherwise, the local-geometry of the
   * reference element might have a different orientation than the geometry of the actual
   * entity in the grid.
   **/
  Geometry geometry () const
  {
    if (!geo_) {
      if (hostElement_) {
        auto localFct = localFunction(Super::gridFunction());
        localFct.bind(*hostElement_);

        auto refElem = referenceElement<ctype, Super::dimension>(hostElement_->type());
        auto localGeometry = refElem.template geometry<codim>(subEntity_);
        geo_ = std::make_shared<GeometryImpl>(Super::type(), std::move(localFct), localGeometry);
      }
      else {
        DUNE_THROW(Dune::NotImplemented, "Geometry of entities of codim!=0 not implemented");
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
245
      }
246
    }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
247

248
249
    return Geometry(*geo_);
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
250

251
252
253
private:
  std::optional<HostElement> hostElement_;
  int subEntity_ = -1;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
254

255
256
257
  using GeometryImpl = typename Traits::template Codim<codim>::GeometryImpl;
  mutable std::shared_ptr<GeometryImpl> geo_;
};
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
258
259


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
template <class G>
class EntityBaseGeometry<0, G>
    : public EntityBase<0, G>
{
  using Super = EntityBase<0, G>;
  using Traits = typename std::remove_const_t<G>::Traits;

public:
  /// \brief type of corresponding geometry
  using Geometry = typename Traits::template Codim<0>::Geometry;

  /// \brief type of corresponding local geometry
  using LocalGeometry = typename Traits::template Codim<0>::LocalGeometry;

public:
  using Super::Super;

  /// \brief obtain the geometry of this entity
  /**
   * The geometry is constructed by parametrization over the host geometry.
   * Internally, the local function is used to construct this parametrization
   * either implicitly, by first interpolating the local function into a local basis
   * or explicitly as reinterpreting the local function directly as geometry.
283
284
285
286
287
288
   *
   * NOTE: The geometry expects a LocalGeometry parametrization for the entity in the
   * grid element. Since this specialization is for grid elements, this parametrization
   * mapping is just the identity. This is implemented by using the DefaultLocalGeometry
   * that simply forwards the input arguments of all the functions or returns an identity
   * object.
289
290
291
292
293
294
295
296
297
   */
  Geometry geometry () const
  {
    if (!geo_) {
      auto localFct = localFunction(Super::gridFunction());
      localFct.bind(Super::hostEntity());
      auto fakeDefaultGeometry = Dune::DefaultLocalGeometry<typename Super::ctype, Super::mydimension, Super::mydimension>{};
      geo_ = std::make_shared<GeometryImpl>(Super::type(), std::move(localFct), fakeDefaultGeometry);
    }
298

299
300
    return Geometry(*geo_);
  }
301

302
303
304
305
private:
  using GeometryImpl = typename Traits::template Codim<0>::GeometryImpl;
  mutable std::shared_ptr<GeometryImpl> geo_;
};
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
306
307


308
309
// Entity
// ------
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
310

311
312
313
314
315
template <int codim, int dim, class G>
class Entity
    : public EntityBaseGeometry<codim, G>
{
  using Super = EntityBaseGeometry<codim, G>;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
316

317
318
319
320
public:
  // import constructors from base class
  using Super::Super;
};
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
321
322


323
324
// Entity for codimension 0
// ------------------------
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
325

326
327
328
329
330
template <int dim, class G>
class Entity<0, dim, G>
    : public EntityBaseGeometry<0, G>
{
  using Super = EntityBaseGeometry<0, G>;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
331

332
333
334
335
  using Traits = typename std::remove_const_t<G>::Traits;
  using Grid = typename Traits::Grid;
  using GridFunction = typename Grid::GridFunction;
  using HostGrid = typename Traits::HostGrid;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
336

337
public:
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
338

339
340
  /** \name Types Required by DUNE
   *  \{ */
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
341

342
343
  /// \brief type of corresponding local geometry
  using LocalGeometry = typename Traits::template Codim<0>::LocalGeometry;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
344

345
346
  /// \brief facade type for entities
  using EntityFacade = Dune::Entity<0, dim, G, Dune::Curved::Entity>;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
347

348
349
  /// \brief type of hierarchic iterator
  using HierarchicIterator = typename Traits::HierarchicIterator;
Praetorius, Simon's avatar
Praetorius, Simon committed
350

351
352
  /// \brief type of leaf intersection iterator
  using LeafIntersectionIterator = typename Traits::LeafIntersectionIterator;
Praetorius, Simon's avatar
Praetorius, Simon committed
353

354
355
  /// \brief type of level intersection iterator
  using LevelIntersectionIterator = typename Traits::LevelIntersectionIterator;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
356

357
  /** \} */
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
358

359
360
  // import constructors from base class
  using Super::Super;
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
361

362
363
364
365
366
367
  template <int codim>
  typename Grid::template Codim<codim>::Entity subEntity (int i) const
  {
    using EntityImpl = typename Traits::template Codim<codim>::EntityImpl;
    return EntityImpl(Super::gridFunction(), Super::hostEntity(), i);
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
368

369
370
371
372
373
  LevelIntersectionIterator ilevelbegin () const
  {
    using IteratorImpl = Curved::IntersectionIterator<Grid, typename HostGrid::LevelIntersectionIterator>;
    return IteratorImpl(*this, Super::hostEntity().ilevelbegin());
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
374

375
376
377
378
379
  LevelIntersectionIterator ilevelend () const
  {
    using IteratorImpl = Curved::IntersectionIterator<Grid, typename HostGrid::LevelIntersectionIterator>;
    return IteratorImpl(*this, Super::hostEntity().ilevelend());
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
380

381
382
383
384
385
  LeafIntersectionIterator ileafbegin () const
  {
    using IteratorImpl = Curved::IntersectionIterator<Grid, typename HostGrid::LeafIntersectionIterator>;
    return IteratorImpl(*this, Super::hostEntity().ileafbegin());
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
386

387
388
389
390
391
  LeafIntersectionIterator ileafend () const
  {
    using IteratorImpl = Curved::IntersectionIterator<Grid, typename HostGrid::LeafIntersectionIterator>;
    return IteratorImpl(*this, Super::hostEntity().ileafend());
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
392

393
394
395
396
  bool hasBoundaryIntersections () const
  {
    return Super::hostEntity().hasBoundaryIntersections();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
397

398
399
400
401
  bool isLeaf () const
  {
    return Super::hostEntity().isLeaf();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
402

403
404
405
406
  EntityFacade father () const
  {
    return Entity(Super::gridFunction(), Super::hostEntity().father());
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
407

408
409
410
411
  bool hasFather () const
  {
    return Super::hostEntity().hasFather();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
412

413
414
415
416
  LocalGeometry geometryInFather () const
  {
    return Super::hostEntity().geometryInFather();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
417

418
419
420
421
422
  HierarchicIterator hbegin (int maxLevel) const
  {
    using IteratorImpl = Curved::HierarchicIterator<G>;
    return IteratorImpl(Super::gridFunction(), Super::hostEntity().hbegin(maxLevel));
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
423

424
425
426
427
428
  HierarchicIterator hend (int maxLevel) const
  {
    using IteratorImpl = Curved::HierarchicIterator<G>;
    return IteratorImpl(Super::gridFunction(), Super::hostEntity().hend(maxLevel));
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
429

430
431
432
433
  bool isRegular () const
  {
    return Super::hostEntity().isRegular();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
434

435
436
437
438
  bool isNew () const
  {
    return Super::hostEntity().isNew();
  }
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
439

440
441
442
443
444
  bool mightVanish () const
  {
    return Super::hostEntity().mightVanish();
  }
};
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
445

446
447
} // end namespace Curved
} // end namespace Dune
Stenger, Florian's avatar
v0.1.0    
Stenger, Florian committed
448

449
#endif // DUNE_CURVEDSURFACEGRID_ENTITY_HH