1 #ifndef DUNE_SPGRID_INTERSECTION_HH 2 #define DUNE_SPGRID_INTERSECTION_HH 3 4 #include <type_traits> 5 6 #include <dune/common/typetraits.hh> 7 8 #include <dune/geometry/type.hh> 9 10 #include <dune/grid/common/intersection.hh> 11 12 #include <dune/grid/spgrid/geometry.hh> 13 #include <dune/grid/spgrid/normal.hh> 14 15 namespace Dune 16 { 17 18 // External Forward Declarations 19 // ----------------------------- 20 21 template< int, int, class > 22 class SPEntity; 23 24 25 26 // SPIntersection 27 // -------------- 28 29 /** 30 * \class SPIntersection 31 * 32 * \tparam Grid type of the \ref Dune::SPGrid "SPGrid" this intersection 33 * belongs to 34 */ 35 template< class Grid > 36 class SPIntersection 37 { 38 typedef SPIntersection< Grid > This; 39 40 typedef typename std::remove_const< Grid >::type::Traits Traits; 41 42 typedef typename Traits::ReferenceCube ReferenceCube; 43 44 public: 45 typedef typename ReferenceCube::ctype ctype; 46 47 static const int dimension = ReferenceCube::dimension; 48 static const int mydimension = dimension-1; 49 static const int dimensionworld = dimension; 50 51 typedef typename Traits::template Codim< 0 >::Entity Entity; 52 53 typedef typename Traits::template Codim< 1 >::Geometry Geometry; 54 typedef typename Traits::template Codim< 1 >::LocalGeometry LocalGeometry; 55 56 private: 57 typedef SPEntity< 0, dimension, Grid > EntityImpl; 58 typedef SPGeometry< mydimension, dimension, Grid > GeometryImpl; 59 60 public: 61 typedef typename EntityImpl::EntityInfo ElementInfo; 62 typedef __SPGrid::EntityInfo< Grid, 1 > EntityInfo; 63 64 typedef typename EntityImpl::GridLevel GridLevel; 65 66 typedef typename GeometryImpl::LocalVector LocalVector; 67 typedef SPNormalVector< ctype, dimensionworld > NormalVector; 68 69 private: 70 typedef typename EntityInfo::MultiIndex MultiIndex; 71 72 typedef typename GridLevel::Mesh Mesh; 73 typedef typename GridLevel::PartitionList PartitionList; 74 typedef typename PartitionList::Partition Partition; 75 76 public: 77 SPIntersection () = default; 78 SPIntersection(const ElementInfo & insideInfo,int face)79 SPIntersection ( const ElementInfo &insideInfo, int face ) 80 : normalId_( face ), 81 insideInfo_( insideInfo ) 82 {} 83 SPIntersection(const EntityInfo & entityInfo,int face)84 SPIntersection ( const EntityInfo &entityInfo, int face ) 85 : normalId_( face ), 86 insideInfo_( entityInfo.gridLevel(), entityInfo.id() - normalId_, entityInfo.partitionNumber() ) 87 {} 88 boundary() const89 bool boundary () const 90 { 91 return (insideInfo_.id()[ normalId_.axis() ] + normalId_.sign() == 2*gridLevel().globalMesh().bound( normalId_ )); 92 } 93 boundaryId() const94 int boundaryId () const 95 { 96 return (boundary() ? (indexInInside()+1) : 0); 97 } 98 boundarySegmentIndex() const99 std::size_t boundarySegmentIndex () const 100 { 101 assert( boundary() ); 102 return gridLevel().boundaryIndex( insideInfo_.id(), insideInfo_.partitionNumber(), normalId_.face() ); 103 } 104 neighbor() const105 bool neighbor () const 106 { 107 const Partition &partition = gridLevel().template partition< All_Partition >().partition( insideInfo_.partitionNumber() ); 108 return ((insideInfo_.id()[ normalId_.axis() ] + normalId_.sign() != partition.bound( normalId_ )) || partition.hasNeighbor( indexInInside() )); 109 } 110 inside() const111 Entity inside () const { return Entity( EntityImpl( insideInfo_ ) ); } 112 113 Entity outside () const; 114 conforming() const115 bool conforming () const 116 { 117 return true; 118 } 119 geometryInInside() const120 LocalGeometry geometryInInside () const 121 { 122 return gridLevel().grid().localFaceGeometry( indexInInside() ); 123 } 124 geometryInOutside() const125 LocalGeometry geometryInOutside () const 126 { 127 return gridLevel().grid().localFaceGeometry( indexInOutside() ); 128 } 129 geometry() const130 Geometry geometry () const 131 { 132 return Geometry( GeometryImpl( entityInfo() ) ); 133 } 134 type() const135 GeometryType type () const { return GeometryTypes::cube( mydimension ); } 136 indexInInside() const137 int indexInInside () const { return normalId_.face(); } indexInOutside() const138 int indexInOutside () const { return (-normalId_).face(); } 139 outerNormal(const LocalVector & local) const140 NormalVector outerNormal ( const LocalVector &local ) const 141 { 142 return unitOuterNormal( local ); 143 } 144 integrationOuterNormal(const LocalVector & local) const145 NormalVector integrationOuterNormal ( const LocalVector &local ) const 146 { 147 return gridLevel().faceVolume( indexInInside() ) * centerUnitOuterNormal(); 148 } 149 centerUnitOuterNormal() const150 NormalVector centerUnitOuterNormal () const { return normalId_; } 151 unitOuterNormal(const LocalVector & local) const152 NormalVector unitOuterNormal ( const LocalVector &local ) const { return normalId_; } 153 equals(const This & other) const154 bool equals ( const This &other ) const 155 { 156 return (indexInInside() == other.indexInInside()) && insideInfo_.equals( other.insideInfo_ ); 157 } 158 gridLevel() const159 const GridLevel &gridLevel () const { return insideInfo_.gridLevel(); } 160 setInside(const ElementInfo & insideInfo)161 void setInside ( const ElementInfo &insideInfo ) { insideInfo_ = insideInfo; } 162 setEntityInfo(const EntityInfo & entityInfo)163 void setEntityInfo ( const EntityInfo &entityInfo ) 164 { 165 insideInfo_ = ElementInfo( entityInfo.gridLevel(), entityInfo.id() - normalId_, entityInfo.partitionNumber() ); 166 } 167 entityInfo() const168 EntityInfo entityInfo () const 169 { 170 return EntityInfo( gridLevel(), insideInfo_.id() + normalId_, insideInfo_.partitionNumber() ); 171 } 172 173 private: 174 SPNormalId< dimension > normalId_; 175 ElementInfo insideInfo_; 176 }; 177 178 179 180 // Implementation of SPIntersection 181 // -------------------------------- 182 183 template< class Grid > 184 inline typename SPIntersection< Grid >::Entity outside() const185 SPIntersection< Grid >::outside () const 186 { 187 MultiIndex id = insideInfo_.id() + normalId_ + normalId_; 188 if( !boundary() ) 189 return Entity( EntityImpl( ElementInfo( gridLevel(), id, insideInfo_.partitionNumber() ) ) ); 190 191 const PartitionList &allPartition = gridLevel().template partition< All_Partition >(); 192 const Partition &partition = allPartition.partition( insideInfo_.partitionNumber() ); 193 194 assert( partition.hasNeighbor( indexInInside() ) ); 195 const Partition &nbPartition = allPartition.partition( partition.neighbor( indexInInside() ) ); 196 197 // manipulate id in case of periodic (i.e., transformed) neighbors 198 const int bound = nbPartition.bound( -normalId_ ); 199 id[ normalId_.axis() ] = bound + normalId_.sign()*(1 - (bound & 1)); 200 return Entity( EntityImpl( ElementInfo( gridLevel(), id, nbPartition.number() ) ) ); 201 } 202 203 } // namespace Dune 204 205 #endif // #ifndef DUNE_SPGRID_INTERSECTION_HH 206