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