Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : ////////////////////////////////////////////////////////////////////////
34 : ////////////////////////////////////////////////////////////////////////
35 : // ...
36 : ////////////////////////////////////////////////////////////////////////
37 :
38 : #ifndef __H__LIBGRID__SELECTOR_MULTI_GRID__
39 : #define __H__LIBGRID__SELECTOR_MULTI_GRID__
40 :
41 : #include <cassert>
42 : #include "selector_interface.h"
43 : #include "../multi_grid.h"
44 : #include "../lib_grid_messages.h"
45 :
46 : namespace ug
47 : {
48 : ////////////////////////////////////////////////////////////////////////
49 : // predeclarations
50 : class MultiGrid;
51 :
52 : /** \ingroup lib_grid_tools
53 : * \{ */
54 :
55 : ////////////////////////////////////////////////////////////////////////
56 : ////////////////////////////////////////////////////////////////////////
57 : // MGSelector
58 : /// specialization of ISelector for grids of class MultiGrid.
59 : /** A selector is a useful class, that allows the user to mark
60 : * elements of a grid as selected or deselected.
61 : * The selection status is maintained even if new elements
62 : * are created or old ones deleted. Features like
63 : * autoselection and selection_inheritance allow users to
64 : * follow the creation and removal of elements in all kind of
65 : * algorithms.
66 : *
67 : * Please note that the selector has to be registered at a
68 : * grid before it may be used. You may register it using the constructor
69 : * or the method assign_grid.
70 : *
71 : * This is a specialization of ISelector for the MultiGrid class.
72 : *
73 : * The following methods are the most used:
74 : * - select, deselect, is_selected (see ISelector)
75 : * - begin, end, num, clear.
76 : *
77 : * Note that the number of levels in the MGSelector always matches the number
78 : * of levels in the associated multigrid. This is guaranteed through a callback
79 : * mechanism.
80 : *
81 : * You may specify the element-type on which begin, end, num and clear
82 : * operate via a template parameter, and the level via a
83 : * normal int-parameter:
84 : *
85 : * \code
86 : * MultiGrid mg;
87 : * MGSelector sel(mg);
88 : *
89 : * // ... create elements and select some
90 : *
91 : * // number of selected vertices on level 1
92 : * int nSelVrts = sel.num<Vertex>(1);
93 : *
94 : * // total number of selected triangles
95 : * int nSelTris = sel.num<Triangle>();
96 : *
97 : * // iteration over all faces
98 : * for(uint i = 0; i < sel.num_levels(); ++i){
99 : * for(FaceIterator iter = sel.begin<Face>(i);
100 : * iter != sel.end<Face>(i); ++iter){
101 : * // ...
102 : * }
103 : * }
104 : * \endcode
105 : */
106 :
107 : class UG_API MGSelector : public ISelector
108 : {
109 : public:
110 : typedef ISelector BaseClass;
111 : typedef MultiGrid grid_type;
112 :
113 : /** This iterator is used by MGSelector to provide iteration across all levels.
114 : * The TMGSelector and TLevelIterator template argument allows to use this
115 : * iterator for const and non-const use.*/
116 : template <class TElem, class TMGSelector, class TLevelIterator>
117 : class MGSelectionIterator
118 : {
119 : public:
120 : typedef MGSelectionIterator this_type;
121 : typedef std::forward_iterator_tag iterator_category;
122 : typedef size_t difference_type;
123 : typedef TElem** pointer;
124 : typedef TElem* value_type;
125 : typedef value_type& reference;
126 :
127 : MGSelectionIterator() : m_sel(NULL), m_lvl(0) {}
128 :
129 : /// copy constructor that allows creation of const-iterators from non-const iterators
130 0 : MGSelectionIterator(const MGSelectionIterator<TElem, MGSelector,
131 : typename geometry_traits<TElem>::iterator>& iter)
132 : {
133 0 : m_sel = iter.m_sel;
134 0 : m_lvl = iter.m_lvl;
135 : m_iter = iter.m_iter;
136 0 : }
137 :
138 0 : this_type operator ++() {increment(); return *this;}
139 0 : this_type operator ++(int unused) {this_type i = *this; increment(); return i;}
140 :
141 : bool operator ==(const this_type& iter) const {return equal(iter);}
142 : bool operator !=(const this_type& iter) const {return !equal(iter);}
143 :
144 : value_type operator *() {return dereference();}
145 : value_type operator *() const {return dereference();}
146 :
147 : private:
148 : friend class MGSelector;
149 : // friend class MGSelectionIterator<TElem, const MGSelector,
150 : // typename MGSelector::traits<TElem>::const_level_iterator>;
151 : typedef TLevelIterator level_iterator;
152 :
153 : MGSelectionIterator(TMGSelector* sel, int lvl,
154 : level_iterator iter)
155 : {
156 0 : m_sel = sel;
157 0 : m_lvl = lvl;
158 : m_iter = iter;
159 : }
160 :
161 : inline bool equal(const this_type& other) const
162 : {
163 : return m_iter == other.m_iter;
164 : }
165 :
166 : /// returns next valid iterator
167 0 : void increment()
168 : {
169 : ++m_iter;
170 0 : while((m_iter == m_sel->template end<TElem>(m_lvl))
171 0 : && (m_lvl + 1 < m_sel->num_levels()))
172 : {
173 0 : ++m_lvl;
174 0 : m_iter = m_sel->template begin<TElem>(m_lvl);
175 : }
176 0 : }
177 :
178 : /// dereference
179 : inline value_type dereference() const
180 : {
181 : return *m_iter;
182 : }
183 :
184 : private:
185 : TMGSelector* m_sel;
186 : size_t m_lvl;
187 : level_iterator m_iter;
188 : };
189 :
190 : /// The traits class holds some important types for each element-type
191 : template <class TElem>
192 : struct traits{
193 : typedef TElem* value_t;
194 : typedef typename geometry_traits<TElem>::iterator level_iterator;
195 : typedef typename geometry_traits<TElem>::const_iterator const_level_iterator;
196 : typedef MGSelectionIterator<TElem, MGSelector,
197 : level_iterator> iterator;
198 : typedef MGSelectionIterator<TElem, const MGSelector,
199 : const_level_iterator> const_iterator;
200 : };
201 :
202 :
203 : MGSelector(uint supportedElements = SE_ALL);
204 : MGSelector(MultiGrid& grid, uint supportedElements = SE_ALL);
205 : virtual ~MGSelector();
206 :
207 : void assign_grid(MultiGrid& grid);
208 : void assign_grid(MultiGrid* grid);
209 0 : inline MultiGrid* multi_grid() {return m_pMultiGrid;}
210 :
211 : /// set the type of elements that shall be handled by the Selector.
212 : /** Pass an or-combination of constants enumerated in SelectorElements.
213 : * \sa Selector::enable_element_support*/
214 : // forwards to protected ISelector method. This rather complicated setup
215 : // is required to avoid virtual method calls during construction.
216 : inline void set_supported_elements(uint shElements);
217 :
218 : /// enable support for element-types. Does not invalidate previous settings.
219 : /** pass an or-combination of constants enumerated in SelectorElements.*/
220 : // forwards to protected ISelector method. This rather complicated setup
221 : // is required to avoid virtual method calls during construction.
222 : inline void enable_element_support(uint shElements);
223 :
224 : /// disable support for element-types.
225 : /** pass an or-combination of constants enumerated in SelectorElements.*/
226 : // forwards to protected ISelector method. This rather complicated setup
227 : // is required to avoid virtual method calls during construction.
228 : void disable_element_support(uint shElements);
229 :
230 : inline size_t num_levels() const {return m_levels.size();}
231 : inline size_t top_level() const
232 : {
233 : size_t l = m_levels.size();
234 0 : if(l == 0)
235 : return 0;
236 : else
237 0 : return l - 1;
238 : }
239 :
240 : virtual void clear();
241 :
242 : template <class TElem>
243 : inline void clear();
244 :
245 : void clear(int level);
246 :
247 : template <class TElem>
248 : inline void clear(int level);
249 :
250 : template <class TElem>
251 : inline size_t num(int level) const;
252 :
253 : inline size_t num(int level) const;
254 :
255 : template <class TElem>
256 : inline size_t num() const;
257 :
258 : inline size_t num() const;
259 :
260 : // empty
261 : inline bool empty(int level) const;
262 :
263 : template <class TElem>
264 : inline bool empty(int level) const;
265 :
266 : inline bool empty() const;
267 :
268 : template <class TElem>
269 : inline bool empty() const;
270 :
271 : // begin
272 : template <class TElem>
273 : inline typename traits<TElem>::iterator
274 : begin();
275 :
276 : template <class TElem>
277 : inline typename traits<TElem>::const_iterator
278 : begin() const;
279 :
280 : template <class TElem>
281 : inline typename traits<TElem>::level_iterator
282 : begin(int level);
283 :
284 : template <class TElem>
285 : inline typename traits<TElem>::const_level_iterator
286 : begin(int level) const;
287 :
288 : // end
289 : template <class TElem>
290 : inline typename traits<TElem>::iterator
291 : end();
292 :
293 : template <class TElem>
294 : inline typename traits<TElem>::const_iterator
295 : end() const;
296 :
297 : template <class TElem>
298 : inline typename traits<TElem>::level_iterator
299 : end(int level);
300 :
301 : template <class TElem>
302 : inline typename traits<TElem>::const_level_iterator
303 : end(int level) const;
304 :
305 : // convenience begin and end
306 0 : inline traits<Vertex>::level_iterator vertices_begin(int level) {return begin<Vertex>(level);}
307 0 : inline traits<Vertex>::level_iterator vertices_end(int level) {return end<Vertex>(level);}
308 0 : inline traits<Edge>::level_iterator edges_begin(int level) {return begin<Edge>(level);}
309 0 : inline traits<Edge>::level_iterator edges_end(int level) {return end<Edge>(level);}
310 0 : inline traits<Face>::level_iterator faces_begin(int level) {return begin<Face>(level);}
311 0 : inline traits<Face>::level_iterator faces_end(int level) {return end<Face>(level);}
312 0 : inline traits<Volume>::level_iterator volumes_begin(int level) {return begin<Volume>(level);}
313 0 : inline traits<Volume>::level_iterator volumes_end(int level) {return end<Volume>(level);}
314 :
315 : /// returns the first selected element of the given type on the specified level.
316 : /** Make sure that elements of the given type exist!
317 : * Behaviour is undefined, if not.*/
318 : template <class TElem> TElem* front(int level);
319 :
320 : /// returns the last selected element of the given type on the specified level.
321 : /** Make sure that elements of the given type exist!
322 : * Behaviour is undefined, if not.*/
323 : template <class TElem> TElem* back(int level);
324 :
325 : // geometric-object-collection
326 : virtual GridObjectCollection get_grid_objects() const;
327 :
328 : // callbacks that allows us to clean-up
329 : // derived from GridObserver
330 : /*
331 : virtual void registered_at_grid(Grid* grid);
332 : virtual void unregistered_from_grid(Grid* grid);
333 : */
334 : virtual void grid_to_be_destroyed(Grid* grid);
335 :
336 : /// returns true if the selector contains vertices
337 0 : virtual bool contains_vertices() const {return num<Vertex>() > 0;}
338 :
339 : /// returns true if the selector contains edges
340 0 : virtual bool contains_edges() const {return num<Edge>() > 0;}
341 :
342 : /// returns true if the selector contains faces
343 0 : virtual bool contains_faces() const {return num<Face>() > 0;}
344 :
345 : /// returns true if the selector contains volumes
346 0 : virtual bool contains_volumes() const {return num<Volume>() > 0;}
347 :
348 : protected:
349 : void clear_lists();
350 :
351 : virtual void add_to_list(Vertex* elem);
352 : virtual void add_to_list(Edge* elem);
353 : virtual void add_to_list(Face* elem);
354 : virtual void add_to_list(Volume* elem);
355 :
356 : virtual void erase_from_list(Vertex* elem);
357 : virtual void erase_from_list(Edge* elem);
358 : virtual void erase_from_list(Face* elem);
359 : virtual void erase_from_list(Volume* elem);
360 :
361 : protected:
362 : using ISelector::AttachedVertexList;
363 : using ISelector::AttachedEdgeList;
364 : using ISelector::AttachedFaceList;
365 : using ISelector::AttachedVolumeList;
366 :
367 : using ISelector::VertexSectionContainer;
368 : using ISelector::EdgeSectionContainer;
369 : using ISelector::FaceSectionContainer;
370 : using ISelector::VolumeSectionContainer;
371 :
372 : struct Level{
373 : VertexSectionContainer m_vertices;
374 : EdgeSectionContainer m_edges;
375 : FaceSectionContainer m_faces;
376 : VolumeSectionContainer m_volumes;
377 : };
378 : typedef std::vector<Level*> LevelVec;
379 :
380 : protected:
381 : /// returns the section container for the given type, subset and level
382 : template <class TElem> inline
383 : typename Grid::traits<TElem>::SectionContainer&
384 : section_container(int level);
385 :
386 : /// returns the const section container for the given type, subset and level
387 : template <class TElem> inline
388 : const typename Grid::traits<TElem>::SectionContainer&
389 : section_container(int level) const;
390 :
391 : template <class TElem>
392 : inline int get_section_index() const;
393 :
394 : inline void level_required(int newSize);
395 : void add_level();
396 :
397 : /// This method should only be called if a complete cleanup is required.
398 : void cleanup();
399 :
400 : /// returns the iterator at which the given element lies in the section container
401 : /** This method may only be called if the element is indeed selected
402 : * \{
403 : */
404 : inline VertexSectionContainer::iterator
405 0 : get_level_iterator(Vertex* o)
406 : {
407 : assert(is_selected(o) && "object not selected.");
408 0 : return section_container<Vertex>(m_pMultiGrid->get_level(o)).
409 0 : get_container().get_iterator(o);
410 : }
411 :
412 : inline EdgeSectionContainer::iterator
413 0 : get_level_iterator(Edge* o)
414 : {
415 : assert(is_selected(o) && "object not selected");
416 0 : return section_container<Edge>(m_pMultiGrid->get_level(o)).
417 0 : get_container().get_iterator(o);
418 : }
419 :
420 : inline FaceSectionContainer::iterator
421 0 : get_level_iterator(Face* o)
422 : {
423 : assert(is_selected(o) && "object not selected");
424 0 : return section_container<Face>(m_pMultiGrid->get_level(o)).
425 0 : get_container().get_iterator(o);
426 : }
427 :
428 : inline VolumeSectionContainer::iterator
429 0 : get_level_iterator(Volume* o)
430 : {
431 : assert(is_selected(o) && "object not selected");
432 0 : return section_container<Volume>(m_pMultiGrid->get_level(o)).
433 0 : get_container().get_iterator(o);
434 : }
435 : /** \} */
436 :
437 : /// callback for multigrid messages
438 : void multigrid_changed(const GridMessage_MultiGridChanged& gm);
439 :
440 : private:
441 : MGSelector(const MGSelector& sel){};///< Copy Constructor not yet implemented!
442 :
443 : protected:
444 : MultiGrid* m_pMultiGrid;
445 : LevelVec m_levels;
446 : VertexIterator m_tmpVBegin;
447 : VertexIterator m_tmpVEnd;
448 :
449 : // callback-id (automatically unregisters callback, when the selector is deleted).
450 : MessageHub::SPCallbackId m_callbackId;
451 :
452 : // we use a shared attachment for the entry-lists of all section containers
453 : AttachedVertexList::AEntry m_aSharedEntryVRT;
454 : AttachedEdgeList::AEntry m_aSharedEntryEDGE;
455 : AttachedFaceList::AEntry m_aSharedEntryFACE;
456 : AttachedVolumeList::AEntry m_aSharedEntryVOL;
457 : };
458 :
459 : /** \} */
460 :
461 : }// end of namespace
462 :
463 : ////////////////////////////////
464 : // include implementation
465 : #include "selector_multi_grid_impl.hpp"
466 :
467 : #endif
|