1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_GRID_COMMON_ENTITY_HH
4 #define DUNE_GRID_COMMON_ENTITY_HH
5 
6 #include <type_traits>
7 
8 #include <dune/common/iteratorrange.hh>
9 #include <dune/common/typetraits.hh>
10 
11 #include <dune/geometry/dimension.hh>
12 #include <dune/geometry/referenceelements.hh>
13 
14 #include "grid.hh"
15 #include "rangegenerators.hh"
16 
17 namespace Dune
18 {
19 
20   /**
21      @brief Wrapper class for entities
22 
23      \tparam cd Codimension of the entity
24      \tparam dim Dimension of the grid
25      \tparam GridImp Type that is a model of Dune::Grid
26      \tparam EntityImp Class template that is a model of Dune::Entity
27 
28 
29      <H3>Engine Concept</H3>
30 
31      This class wraps a object of type EntityImp and forwards all member
32      function calls to corresponding members of this class. In that sense Entity
33      defines the interface and EntityImp supplies the implementation.
34      For various reasons we do not use an inheritance hierarchy and the
35      Barton-Nackman trick here.
36 
37 
38      <H3>Specialization</H3>
39 
40      The Entity class template is specialized for <tt>cd=0</tt> (elements,
41      Dune::Entity<0,dim,GridImp,EntityImp>).
42      This case has an extended interface.
43      The methods defined in the general template
44      are provided by the specialization as well. We did not use inheritance
45      because different implementations for different codimensions may be required
46      and virtual functions had to be avoided.
47 
48      <H3>View concept</H3>
49 
50      Entities can not be created, assigned or otherwise modified outside
51      the interface in the user code. They are only accessible by immutable
52      iterators provided on the corresponding grid class.
53 
54      The only way to modify the entities of a grid is through grid adaptation which
55      consists of tagging entities (of codimension 0) for refinement and then
56      calling the adapt() method on the grid.
57 
58 
59      \ingroup GIEntity
60      \nosubgrouping
61    */
62   template<int cd, int dim, class GridImp, template<int,int,class> class EntityImp>
63   class Entity
64   {
65   public:
66     /**
67      * \brief type of underlying implementation
68      *
69      * \warning Implementation details may change without prior notification.
70      **/
71     typedef EntityImp< cd, dim, GridImp > Implementation;
72 
73     /**
74      * \brief access to the underlying implementation
75      *
76      * \warning Implementation details may change without prior notification.
77      **/
impl()78     Implementation &impl () { return realEntity; }
79     /**
80      * \brief access to the underlying implementation
81      *
82      * \warning Implementation details may change without prior notification.
83      **/
impl() const84     const Implementation &impl () const { return realEntity; }
85 
86   protected:
87     Implementation realEntity;
88 
89   public:
90 
91     //===========================================================
92     /** @name Exported types and constants
93      */
94     //@{
95     //===========================================================
96 
97     //! \brief The corresponding geometry type
98     typedef typename GridImp::template Codim<cd>::Geometry Geometry;
99 
100     //! \brief The corresponding entity seed (for storage of entities)
101     typedef typename GridImp::template Codim<cd>::EntitySeed EntitySeed;
102 
103     enum {
104       //! \brief Know your own codimension.
105       codimension=cd
106     };
107     enum {
108       //! \brief Know the grid dimension.
109       dimension=dim
110     };
111     enum {
112       //! \brief Dimensionality of the reference element of the entity.
113       mydimension=dim-cd
114     };
115     //@}
116 
117 
118 
119     //===========================================================
120     /** @name Methods shared by entities of all codimensions
121      */
122     //@{
123     //===========================================================
124 
125     //! The level of this entity
level() const126     int level () const { return realEntity.level(); }
127 
128     //! Partition type of this entity
partitionType() const129     PartitionType partitionType () const { return realEntity.partitionType(); }
130 
131     /** \brief obtain geometric realization of the entity
132      *
133      *  Each entity provides an object of type
134      *  Dune::Geometry< dimension-codimension, dimensionworld, ... > that
135      *  represents the map from a reference element to world coordinates.
136      *
137      *  \note Previously, the geometry was encapsulated in the entity object and
138      *        a const reference was returned.
139      *
140      *  \note The returned geometry object is guaranteed to remain valid until the
141      *        grid is modified (or deleted).
142      */
geometry() const143     Geometry geometry () const { return realEntity.geometry(); }
144 
145     /** \brief Return the name of the reference element. The type can
146        be used to access the Dune::ReferenceElement.
147      */
type() const148     GeometryType type () const { return realEntity.type(); }
149 
150     /**
151      * \brief Number of subentities for a given codimension
152      *
153      * \param  codim  codimension to obtain number of subentities for
154      *
155      * \note The codimension is specified with respect to the grid dimension.
156      *
157      * \note Unless the geometry type is None, this method is redundant and
158      *       the same information can be obtained from the corresponding
159      *       reference element.
160      **/
subEntities(unsigned int codim) const161     unsigned int subEntities ( unsigned int codim ) const
162     {
163       return realEntity.subEntities(codim);
164     }
165 
166     /** \brief Return the entity seed which contains sufficient information
167      *  to generate the entity again and uses as little memory as possible
168      */
seed() const169     EntitySeed seed () const { return realEntity.seed(); }
170 
171     //! Compares two entities for equality.
operator ==(const Entity & other) const172     bool operator==(const Entity& other) const
173     {
174       return realEntity.equals(other.realEntity);
175     }
176 
177     //! Compares two entities for inequality.
operator !=(const Entity & other) const178     bool operator!=(const Entity& other) const
179     {
180       return !realEntity.equals(other.realEntity);
181     }
182 
Entity()183     Entity()
184     {}
185 
186     //! Copy constructor from an existing entity.
Entity(const Entity & other)187     Entity(const Entity& other)
188       : realEntity(other.realEntity)
189     {}
190 
191     //! Move constructor from an existing entity.
Entity(Entity && other)192     Entity(Entity&& other)
193       : realEntity(std::move(other.realEntity))
194     {}
195 
196     //! Copy assignment operator from an existing entity.
operator =(const Entity & other)197     Entity& operator=(const Entity& other)
198     {
199       realEntity = other.realEntity;
200       return *this;
201     }
202 
203     //! Move assignment operator from an existing entity.
operator =(Entity && other)204     Entity& operator=(Entity&& other)
205     {
206       realEntity = std::move(other.realEntity);
207       return *this;
208     }
209 
210     //@}
211 
212     //===========================================================
213     /** @name Interface for the implementor
214      */
215     //@{
216     //===========================================================
217 
218     //! Copy constructor from EntityImp
Entity(const EntityImp<cd,dim,GridImp> & e)219     Entity(const EntityImp<cd,dim,GridImp> & e) : realEntity(e) {}
220 
221     //! Move constructor from EntityImp
Entity(EntityImp<cd,dim,GridImp> && e)222     Entity(EntityImp<cd,dim,GridImp> && e) : realEntity(std::move(e)) {}
223 
224     //@}
225   };
226 
227   /**
228      @brief Template specialization of Dune::Entity for Elements (codim==0)
229 
230      \tparam dim Dimension of the grid
231      \tparam GridImp Type that is a model of Dune::Grid
232      \tparam EntityImp Class template that is a model of Dune::Entity
233 
234      @see Dune::Entity (general version) for the full documentation
235 
236      \extends Entity<int cd, int dim, class GridImp, template<int,int,class> class EntityImp>
237 
238      \ingroup GIEntity
239      \nosubgrouping
240    */
241   template<int dim, class GridImp, template<int,int,class> class EntityImp>
242   class Entity <0,dim,GridImp,EntityImp>
243   {
244   public:
245     /**
246      * \brief Type of underlying implementation
247      *
248      * \note This code may change without prior warning
249      *
250      **/
251     typedef EntityImp< 0, dim, GridImp > Implementation;
252 
253     //! Return reference to the real implementation
impl()254     Implementation &impl () { return realEntity; }
255     //! Return const reference to the real implementation
impl() const256     const Implementation &impl () const { return realEntity; }
257 
258   protected:
259     Implementation realEntity;
260 
261   public:
262 
263     //===========================================================
264     /** @name Exported types and constants
265      */
266     //@{
267     //===========================================================
268 
269     /** \brief The geometry type of this entity */
270     typedef typename GridImp::template Codim<0>::Geometry Geometry;
271 
272     //! \brief The corresponding entity seed (for storage of entities)
273     typedef typename GridImp::template Codim<0>::EntitySeed EntitySeed;
274 
275     /** \brief The geometry type of this entity when the geometry is expressed
276        embedded in the father element.
277 
278        This differs from Geometry in particular when dim != dimworld,
279        but even when dim == dimworld the implementation may choose to use
280        a different type here.
281      */
282     typedef typename GridImp::template Codim<0>::LocalGeometry LocalGeometry;
283 
284     /** \brief Entity types of the different codimensions */
285     template <int cd>
286     struct Codim
287     {
288       typedef typename GridImp::template Codim<cd>::Entity Entity;
289     };
290 
291     /** \brief The HierarchicIterator type*/
292     typedef typename GridImp::HierarchicIterator HierarchicIterator;
293 
294     enum {
295       //! Know your own codimension
296       codimension=0
297     };
298     enum {
299       //! Know the grid's dimension
300       dimension=dim
301     };
302     enum {
303       /** \brief Know dimension of the entity */
304       mydimension=dim
305     };
306     //@}
307 
308 
309     //===========================================================
310     /** @name Methods shared by entities of all codimensions
311      */
312     //@{
313     //===========================================================
314 
315     //! @copydoc Dune::Entity::level()
level() const316     int level () const { return realEntity.level(); }
317 
318     //! @copydoc Dune::Entity::partitionType()
partitionType() const319     PartitionType partitionType () const { return realEntity.partitionType(); }
320 
321     //! @copydoc Dune::Entity::geometry()
geometry() const322     Geometry geometry () const { return realEntity.geometry(); }
323 
324     /**
325      * \brief Number of subentities for a given codimension
326      *
327      * \param  codim  codimension to obtain number of subentities for
328      *
329      * \note The codimension is specified with respect to the grid dimension.
330      *
331      * \note Unless the geometry type is None, this method is redundant and
332      *       the same information can be obtained from the corresponding
333      *       reference element.
334      **/
subEntities(unsigned int codim) const335     unsigned int subEntities ( unsigned int codim ) const
336     {
337       return realEntity.subEntities(codim);
338     }
339 
340     /** \brief Return the name of the reference element. The type can
341         be used to access the Dune::ReferenceElement.
342      */
type() const343     GeometryType type () const { return realEntity.type(); }
344 
345     /** \brief Return the entity seed which contains sufficient information
346      *  to generate the entity again and uses as little memory as possible
347      */
seed() const348     EntitySeed seed () const { return realEntity.seed(); }
349 
350     //! Compares two entities for equality.
operator ==(const Entity & other) const351     bool operator==(const Entity& other) const
352     {
353       return realEntity.equals(other.realEntity);
354     }
355 
356     //! Compares two entities for inequality.
operator !=(const Entity & other) const357     bool operator!=(const Entity& other) const
358     {
359       return !realEntity.equals(other.realEntity);
360     }
361 
Entity()362     Entity()
363     {}
364 
365     //! Copy constructor from an existing entity.
Entity(const Entity & other)366     Entity(const Entity& other)
367       : realEntity(other.realEntity)
368     {}
369 
370     //! Move constructor from an existing entity.
Entity(Entity && other)371     Entity(Entity&& other)
372       : realEntity(std::move(other.realEntity))
373     {}
374 
375     //! Copy assignment operator from an existing entity.
operator =(const Entity & other)376     Entity& operator=(const Entity& other)
377     {
378       realEntity = other.realEntity;
379       return *this;
380     }
381 
382     //! Move assignment operator from an existing entity.
operator =(Entity && other)383     Entity& operator=(Entity&& other)
384     {
385       realEntity = std::move(other.realEntity);
386       return *this;
387     }
388 
389     //@}
390 
391     //===========================================================
392     /** @name Extended interface of entities of codimension 0
393      */
394     //@{
395     //===========================================================
396 
397     /** \brief Obtain a subentity
398      *
399      *  \tparam  codim  codimension of the desired subentity
400      *
401      *  \param[in]  i  number of the subentity (in generic numbering)
402      *
403      *  \returns the specified subentity
404      *
405      *  \note The subentities are numbered 0, ..., subEntities( codim )-1
406      */
407     template< int codim >
408     typename Codim< codim >::Entity
subEntity(int i) const409     subEntity ( int i ) const
410     {
411       return realEntity.template subEntity< codim >( i );
412     }
413 
414     /**\brief Inter-level access to father entity on the next-coarser grid.
415        The given entity resulted directly from a subdivision of its father
416        entity. The behaviour for elements on the macro grid, that is when
417        \ref hasFather() is false, is undefined.
418 
419        \note If the partitionType of the Entity is GhostEntity,
420              it is not guaranteed that this method is working
421              or implemented in general.
422              For some grids it might be available, though.
423      */
father() const424     Entity father () const
425     {
426       return realEntity.father();
427     }
428 
429     /**\brief Return true if entity has a father entity which can be accessed
430        using the father() method.
431      */
hasFather() const432     bool hasFather () const
433     {
434       return realEntity.hasFather();
435     }
436 
437     //! Returns true if the entity is contained in the leaf grid
isLeaf() const438     bool isLeaf () const
439     {
440       return realEntity.isLeaf();
441     }
442 
443     /** @brief Returns true if element is of regular type in red/green type refinement.
444        In bisection or hanging node refinement this is always true.
445      */
isRegular() const446     bool isRegular() const { return realEntity.isRegular(); }
447 
448     /** \brief Provides information how this element has been subdivided from its
449      *         father element.
450      *
451      *  The returned LocalGeometry is a model of
452      *  Dune::Geometry<dimension,dimension,...>, mapping the reference element of
453      *  the given entity to the reference element of its father.
454      *
455      *  This information is sufficient to interpolate all degrees of freedom in
456      *  the conforming case.
457      *  Nonconforming may require access to neighbors of the father and
458      *  calculations with local coordinates.
459      *  The on-the-fly case is somewhat inefficient since degrees of freedom may be
460      *  visited several times.
461      *  If we store interpolation matrices, this is tolerable.
462      *  We assume that on-the-fly implementation of interpolation is only done for
463      *  simple discretizations.
464      *
465      *  \note For ghost entities, this method is not guaranteed to be implemented.
466      *
467      *  \note Previously, the geometry was encapsulated in the entity object and
468      *        a const reference was returned.
469      *
470      *  \note The returned geometry object is guaranteed to remain valid until the
471      *        grid is modified (or deleted).
472      */
geometryInFather() const473     LocalGeometry geometryInFather () const { return realEntity.geometryInFather(); }
474 
475     /**\brief Inter-level access to elements that resulted from (recursive)
476        subdivision of this element.
477 
478        \param[in] maxLevel Iterator does not stop at elements with level greater than maxlevel.
479        \return Iterator to the first son (level is not greater than maxlevel)
480 
481        \note If the partitionType of the Entity is GhostEntity,
482            it is not guaranteed that this method is working
483            or implemented in general.
484            For some grids it might be available, though.
485      */
hbegin(int maxLevel) const486     HierarchicIterator hbegin (int maxLevel) const
487     {
488       return realEntity.hbegin(maxLevel);
489     }
490 
491     /** \brief Returns iterator to one past the last son element
492 
493        \note If the partitionType of the Entity is GhostEntity,
494              it is not guaranteed that this method is working
495              or implemented in general.
496              For some grids it might be available, though.
497      */
hend(int maxLevel) const498     HierarchicIterator hend (int maxLevel) const
499     {
500       return realEntity.hend(maxLevel);
501     }
502 
503     /**\brief Returns true, if the entity has been created during the last call to adapt()
504      */
isNew() const505     bool isNew () const { return realEntity.isNew(); }
506 
507     /**\brief Returns true, if entity might disappear during the next call to adapt().
508      * If the method returns false, the entity is guaranteed to still be present after
509      * adaptation.
510      */
mightVanish() const511     bool mightVanish () const { return realEntity.mightVanish(); }
512 
513     /**\brief Returns true, if entity has intersections with boundary
514      */
hasBoundaryIntersections() const515     bool hasBoundaryIntersections () const { return realEntity.hasBoundaryIntersections(); }
516 
517 
518     //===========================================================
519     /** @name Interface for the implementor
520      */
521     //@{
522     //===========================================================
523 
524     //! Copy constructor from EntityImp
Entity(const EntityImp<0,dim,GridImp> & e)525     Entity(const EntityImp<0,dim,GridImp> & e) : realEntity(e) {}
526 
527     //! Move constructor from EntityImp
Entity(EntityImp<0,dim,GridImp> && e)528     Entity(EntityImp<0,dim,GridImp> && e) : realEntity(std::move(e)) {}
529 
530     //@}
531   };
532 
533 
534 
535   //********************************************************************
536   /**
537      @brief Default Implementations for EntityImp
538 
539      EntityDefaultImplementation provides default implementations for Entity which uses
540      the implemented interface which has to be done by the user.
541 
542      @note this is the general version, but there is a specialization for cd=0
543 
544      @ingroup GridDevel
545    */
546   template<int cd, int dim, class GridImp, template<int,int,class> class EntityImp>
547   class EntityDefaultImplementation
548   {
549   public:
550     //! know your own codimension
551     enum { codimension=cd };
552 
553     //! Dimension of the grid
554     enum { dimension=dim };
555 
556     /** \brief Know dimension of the entity */
557     enum { mydimension=dim-cd };
558 
559     //! \brief The corresponding entity seed (for storage of entities)
560     typedef typename GridImp::template Codim<cd>::EntitySeed EntitySeed;
561 
562     /**
563      * \brief Number of subentities for a given codimension
564      *
565      * \param  codim  codimension to obtain number of subentities for
566      *
567      * \note The codimension is specified with respect to the grid dimension.
568      *
569      * \note Unless the geometry type is None, this method is redundant and
570      *       the same information can be obtained from the corresponding
571      *       reference element.
572      **/
subEntities(unsigned int codim) const573     unsigned int subEntities ( unsigned int codim ) const
574     {
575       typedef typename std::remove_const< GridImp >::type::ctype ctype;
576       return ReferenceElements< ctype, mydimension >::general( asImp().type() ).size( codim - codimension );
577     }
578 
579     /** \brief Return the name of the reference element. The type can
580         be used to access the Dune::ReferenceElement.
581      */
type() const582     GeometryType type () const { return asImp().geometry().type(); }
583 
584   private:
585     //!  Barton-Nackman trick
asImp()586     EntityImp<cd,dim,GridImp>& asImp ()
587     {
588       return static_cast<EntityImp<cd,dim,GridImp>&>(*this);
589     }
asImp() const590     const EntityImp<cd,dim,GridImp>& asImp () const
591     {
592       return static_cast<const EntityImp<cd,dim,GridImp>&>(*this);
593     }
594   }; // end EntityDefaultImplementation
595 
596   //********************************************************************
597   /**
598      @brief Default Implementations for EntityImp (Elements [cd=0])
599 
600      EntityDefaultImplementation provides default implementations for Entity which uses
601      the implemented interface which has to be done by the user.
602 
603      \extends EntityDefaultImplementation<int cd, int dim, class GridImp, template<int,int,class> class EntityImp>
604 
605      @ingroup GridDevel
606    */
607   template<int dim, class GridImp, template<int,int,class> class EntityImp>
608   class EntityDefaultImplementation <0,dim,GridImp,EntityImp>
609   {
610   public:
611     //! know your own codimension
612     enum { codimension=0 };
613 
614     //! Dimension of the grid
615     enum { dimension=dim };
616 
617     /** \brief Know dimension of the entity */
618     enum { mydimension=dim };
619 
620     //! \brief The corresponding entity seed (for storage of entities)
621     typedef typename GridImp::template Codim<0>::EntitySeed EntitySeed;
622 
623     /** @brief Returns true if element is of regular type in red/green type refinement.
624        In bisection or hanging node refinement this is always true.
625      */
isRegular() const626     bool isRegular() const { return true; }
627 
628     /**
629      * \brief Number of subentities for a given codimension
630      *
631      * \param  codim  codimension to obtain number of subentities for
632      *
633      * \note The codimension is specified with respect to the grid dimension.
634      *
635      * \note Unless the geometry type is None, this method is redundant and
636      *       the same information can be obtained from the corresponding
637      *       reference element.
638      **/
subEntities(unsigned int codim) const639     unsigned int subEntities ( unsigned int codim ) const
640     {
641       typedef typename std::remove_const< GridImp >::type::ctype ctype;
642       return ReferenceElements< ctype, mydimension >::general( asImp().type() ).size( codim - codimension );
643     }
644 
645     /** \brief Return the name of the reference element. The type can
646         be used to access the Dune::ReferenceElement.
647      */
type() const648     GeometryType type () const { return asImp().geometry().type(); }
649 
650     /**\brief Returns true, if the entity has been created during the last call to adapt()
651      */
isNew() const652     bool isNew () const { return false; }
653 
654     /**\brief Returns true, if entity might disappear during the next call to adapt()
655      */
mightVanish() const656     bool mightVanish () const { return false; }
657 
658     /**\brief Returns true, if entity has intersections with boundary,
659        this implementation uses the Level- and LeafIntersectionIterator to
660        check for boundary intersections
661      */
hasBoundaryIntersections() const662     bool hasBoundaryIntersections () const
663     {
664       typedef typename GridImp::LevelIntersectionIterator IntersectionIterator;
665       IntersectionIterator end = asImp().ilevelend();
666       for (IntersectionIterator it = asImp().ilevelbegin(); it != end; ++it)
667         if( it->boundary() )
668           return true;
669 
670       return false;
671     }
672 
673   private:
674     //  Barton-Nackman trick
asImp()675     EntityImp<0,dim,GridImp>& asImp () { return static_cast<EntityImp<0,dim,GridImp>&>(*this); }
asImp() const676     const EntityImp<0,dim,GridImp>& asImp () const { return static_cast<const EntityImp<0,dim,GridImp>&>(*this); }
677   };
678 
679   //! Second-level dispatch to select the correct reference element for a grid entity.
680   /**
681    * This function is the default implementation of the second-level reference element dispatch
682    * performed by Entity.
683    *
684    * When referenceElement() is called with an Entity, it will forward the call to
685    * `referenceElement<ctype, mydim>(const GeometryType&)`. This default implementation
686    * will do the right thing as long as your geometry is based on a standard Dune ReferenceElement. If
687    * it is not and you want to supply your own reference element implementation, provide an override of
688    * this function for your specific geometry implementation.
689    *
690    * \related Entity
691    */
692   template< int cd, int dim, class GridImp, template<int,int,class> class EntityImp >
referenceElement(const Entity<cd,dim,GridImp,EntityImp> & entity)693   auto referenceElement(const Entity< cd, dim, GridImp, EntityImp >& entity )
694     -> decltype(referenceElement<typename GridImp::ctype,GridImp::template Codim<cd>::Geometry::mydimension>(entity.type()))
695   {
696     typedef typename GridImp::template Codim<cd>::Geometry Geo;
697     return referenceElement< typename Geo::ctype, Geo::mydimension >(entity.type());
698   }
699 }
700 
701 #endif // DUNE_GRID_COMMON_ENTITY_HH
702