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_ONEDGRID_INDEXSETS_HH
4 #define DUNE_ONEDGRID_INDEXSETS_HH
5 
6 /** \file
7     \brief The index and id sets for the OneDGrid class
8  */
9 
10 #include <vector>
11 
12 #include <dune/grid/common/indexidset.hh>
13 
14 #include <dune/grid/onedgrid/onedgridlist.hh>
15 #include <dune/grid/onedgrid/onedgridentity.hh>
16 
17 namespace Dune {
18 
19   template<class GridImp>
20   class OneDGridLevelIndexSet : public IndexSet<GridImp,OneDGridLevelIndexSet<GridImp> >
21   {
22   public:
23 
24     /** \brief Constructor for a given level of a given grid
25      */
OneDGridLevelIndexSet(const GridImp & grid,int level)26     OneDGridLevelIndexSet (const GridImp& grid, int level)
27       : grid_(&grid), level_(level)
28     {}
29 
30     //! get index of an entity
31     template<int cd>
index(const typename GridImp::Traits::template Codim<cd>::Entity & e) const32     int index (const typename GridImp::Traits::template Codim<cd>::Entity& e) const
33     {
34       return e.impl().levelIndex();
35     }
36 
37     //! get index of subentity of an entity
38     template<int cc>
subIndex(const typename GridImp::Traits::template Codim<cc>::Entity & e,int i,unsigned int codim) const39     unsigned int subIndex (const typename GridImp::Traits::template Codim<cc>::Entity& e,
40                            int i,
41                            unsigned int codim) const
42     {
43       return e.impl().subLevelIndex(i,codim);
44     }
45 
46     //! get number of entities of given type and on this level
size(GeometryType type) const47     std::size_t size (GeometryType type) const
48     {
49       return grid_->size(level_,type);
50     }
51 
52     //! get number of entities of given codim, type and on this level
size(int codim) const53     std::size_t size (int codim) const
54     {
55       return grid_->size(level_,codim);
56     }
57 
types(int codim) const58     std::vector< GeometryType > types ( int codim ) const { return myTypes_[ codim ]; }
59 
60     /** \brief Deliver all geometry types used in this grid */
geomTypes(int codim) const61     const std::vector<GeometryType>& geomTypes (int codim) const
62     {
63       return myTypes_[codim];
64     }
65 
66     /** \brief Return true if e is contained in the index set.
67 
68        \warning This implementation takes O(n) time!  It also assumes that e belongs
69        to the correct grid.
70      */
71     template <class EntityType>
contains(const EntityType & e) const72     bool contains (const EntityType& e) const
73     {
74       // If the entity isn't on the same level as this index set it cannot be contained in the index set
75       if (e.level() != level_)
76         return false;
77 
78       enum { cd = EntityType::codimension };
79       typedef typename GridImp::template Codim<cd>::template Partition<All_Partition>::LevelIterator IteratorType;
80       IteratorType iend = grid_->levelGridView(level_).template end<cd,All_Partition>();
81       for (IteratorType it = grid_->levelGridView(level_).template begin<cd,All_Partition>();
82            it != iend; ++it)
83       {
84         if (this->template index<cd>(*it) == this->template index<cd>(e))
85           return true;
86       }
87       return false;
88     }
89 
90     /** \brief Sets the corresponding internal fields.  Used by the GridFactory */
setSizesAndTypes(unsigned int numVertices,unsigned int numElements)91     void setSizesAndTypes(unsigned int numVertices, unsigned int numElements) {
92 
93       numVertices_ = numVertices;
94       numElements_ = numElements;
95 
96       // ///////////////////////////////////////////////
97       //   Update the list of geometry types present
98       // ///////////////////////////////////////////////
99       if (numElements_>0) {
100         myTypes_[0].resize(1);
101         myTypes_[0][0] = GeometryTypes::line;
102       } else
103         myTypes_[0].resize(0);
104 
105       if (numVertices_>0) {
106         myTypes_[1].resize(1);
107         myTypes_[1][0] = GeometryTypes::vertex;
108       } else
109         myTypes_[1].resize(0);
110 
111     }
112 
113     /** \todo Should be private */
update()114     void update() {
115 
116       // ///////////////////////////////
117       //   Init the element indices
118       // ///////////////////////////////
119       numElements_ = 0;
120       OneDGridList<OneDEntityImp<1> >::const_iterator eIt;
121       for (eIt = grid_->elements(level_).begin(); eIt != grid_->elements(level_).end(); eIt = eIt->succ_)
122         /** \todo Remove this const cast */
123         const_cast<OneDEntityImp<1>*>(eIt)->levelIndex_ = numElements_++;
124 
125       // //////////////////////////////
126       //   Init the vertex indices
127       // //////////////////////////////
128 
129       numVertices_ = 0;
130       OneDGridList<OneDEntityImp<0> >::const_iterator vIt;
131       for (vIt = grid_->vertices(level_).begin(); vIt != grid_->vertices(level_).end(); vIt = vIt->succ_)
132         /** \todo Remove this const cast */
133         const_cast<OneDEntityImp<0>*>(vIt)->levelIndex_ = numVertices_++;
134 
135       // set the list of geometry types
136       setSizesAndTypes(numVertices_, numElements_);
137     }
138 
139   private:
140     const GridImp* grid_;
141     int level_;
142 
143     int numElements_;
144     int numVertices_;
145 
146     /** \brief The GeometryTypes present for each codim */
147     std::vector<GeometryType> myTypes_[2];
148   };
149 
150   template<class GridImp>
151   class OneDGridLeafIndexSet :
152     public IndexSet<GridImp,OneDGridLeafIndexSet<GridImp> >
153   {
154   public:
155     //! constructor stores reference to a grid and level
OneDGridLeafIndexSet(const GridImp & g)156     OneDGridLeafIndexSet (const GridImp& g) : grid_(g)
157     {}
158 
159     //! get index of an entity
160     /*
161        We use the remove_const to extract the Type from the mutable class,
162        because the const class is not instantiated yet.
163      */
164     template<int cd>
index(const typename std::remove_const<GridImp>::type::Traits::template Codim<cd>::Entity & e) const165     int index (const typename std::remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
166     {
167       return e.impl().leafIndex();
168     }
169 
170     //! get index of subentity of an entity
171     template<int cc>
subIndex(const typename std::remove_const<GridImp>::type::Traits::template Codim<cc>::Entity & e,int i,unsigned int codim) const172     int subIndex (const typename std::remove_const<GridImp>::type::Traits::template Codim<cc>::Entity& e,
173                   int i,
174                   unsigned int codim) const
175     {
176       return e.impl().subLeafIndex(i,codim);
177     }
178 
179     //! get number of entities of given codim, type on the leaf level
size(GeometryType type) const180     std::size_t size (GeometryType type) const
181     {
182       if (type.isVertex()) {
183 
184         return numVertices_;
185 
186       } else if (type.isLine()) {
187 
188         return numElements_;
189 
190       }
191 
192       return 0;
193     }
194 
195     //! get number of entities of given codim, type on the leaf level
size(int codim) const196     std::size_t size(int codim) const
197     {
198       if (codim==1) {
199 
200         return numVertices_;
201 
202       } else if (codim==0) {
203 
204         return numElements_;
205 
206       }
207 
208       return 0;
209     }
210 
types(int codim) const211     std::vector< GeometryType > types ( int codim ) const { return myTypes_[ codim ]; }
212 
213     /** deliver all geometry types used in this grid */
geomTypes(int codim) const214     const std::vector<GeometryType>& geomTypes (int codim) const
215     {
216       return myTypes_[codim];
217     }
218 
219     /** \brief Return true if e is contained in the index set.
220 
221        Warning: this implementation takes O(n) time!  It also assumes that e belongs
222        to the correct grid.
223      */
224     template <class EntityType>
contains(const EntityType & e) const225     bool contains (const EntityType& e) const
226     {
227       enum { cd = EntityType::codimension };
228       for (const auto& entity : entities(grid_.leafGridView(), Codim<cd>()))
229       {
230         if (entity.level() == e.level() && this->template index<cd>(entity) == this->template index<cd>(e))
231           return true;
232       }
233       return false;
234     }
235 
236     /** \brief Sets the corresponding internal fields.  Used by the GridFactory */
setSizesAndTypes(unsigned int numVertices,unsigned int numElements)237     void setSizesAndTypes(unsigned int numVertices, unsigned int numElements) {
238 
239       numVertices_ = numVertices;
240       numElements_ = numElements;
241 
242       // ///////////////////////////////////////////////
243       //   Update the list of geometry types present
244       // ///////////////////////////////////////////////
245       if (numElements_>0) {
246         myTypes_[0].resize(1);
247         myTypes_[0][0] = GeometryTypes::line;
248       } else
249         myTypes_[0].resize(0);
250 
251       if (numVertices_>0) {
252         myTypes_[1].resize(1);
253         myTypes_[1][0] = GeometryTypes::vertex;
254       } else
255         myTypes_[1].resize(0);
256 
257     }
258 
259     /** \todo Should be private */
update()260     void update() {
261 
262       // ///////////////////////////////
263       //   Init the element indices
264       // ///////////////////////////////
265       numElements_ = 0;
266       for (const auto& element : elements(grid_.leafGridView()))
267         element.impl().target_->leafIndex_ = numElements_++;
268 
269       // //////////////////////////////
270       //   Init the vertex indices
271       // //////////////////////////////
272 
273       numVertices_ = 0;
274 
275       for (int i=grid_.maxLevel(); i>=0; i--) {
276 
277         const OneDEntityImp<0>* vIt;
278         for (vIt = grid_.vertices(i).begin(); vIt != grid_.vertices(i).end(); vIt = vIt->succ_) {
279 
280           /** \todo Remove the const casts */
281           if (vIt->isLeaf())
282             const_cast<OneDEntityImp<0>*>(vIt)->leafIndex_ = numVertices_++;
283           else
284             const_cast<OneDEntityImp<0>*>(vIt)->leafIndex_ = vIt->son_->leafIndex_;
285 
286         }
287 
288       }
289 
290       // set the list of geometry types
291       setSizesAndTypes(numVertices_, numElements_);
292 
293     }
294 
295   private:
296     const GridImp& grid_;
297 
298     int numElements_;
299     int numVertices_;
300 
301     /** \brief The GeometryTypes present for each codim */
302     std::vector<GeometryType> myTypes_[2];
303   };
304 
305 
306   template<class GridImp>
307   class OneDGridIdSet : public IdSet<GridImp,OneDGridIdSet<GridImp>,unsigned int>
308   {
309   public:
310     //! define the type used for persistent indices
311     typedef unsigned int IdType;
312 
313     //! constructor stores reference to a grid
OneDGridIdSet(const GridImp & g)314     OneDGridIdSet (const GridImp& g) : grid_(g) {}
315 
316     //! get id of an entity
317     /*
318        We use the remove_const to extract the Type from the mutable class,
319        because the const class is not instantiated yet.
320      */
321     template<int cd>
id(const typename std::remove_const<GridImp>::type::Traits::template Codim<cd>::Entity & e) const322     IdType id (const typename std::remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e) const
323     {
324       return e.impl().globalId();
325     }
326 
327     //! get id of subentity
subId(const typename std::remove_const<GridImp>::type::Traits::template Codim<0>::Entity & e,int i,unsigned int codim) const328     IdType subId (const typename std::remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e,
329                   int i,
330                   unsigned int codim) const
331     {
332       return e.impl().subId(i,codim);
333     }
334 
335   private:
336 
337     const GridImp& grid_;
338   };
339 
340 }  // namespace Dune
341 
342 
343 #endif
344