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