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 : #ifndef __H__LIBGRID__SUBSET_HANDLER_GRID__
34 : #define __H__LIBGRID__SUBSET_HANDLER_GRID__
35 :
36 : #include <vector>
37 : #include <cassert>
38 : #include "lib_grid/grid/grid.h"
39 : #include "common/util/section_container.h"
40 : #include "subset_handler_interface.h"
41 :
42 : namespace ug
43 : {
44 :
45 : /** \ingroup lib_grid_tools
46 : * \{ */
47 :
48 : ////////////////////////////////////////////////////////////////////////
49 : // GridSubsetHandler
50 : /// Partitions elements of a grid into several subsets.
51 : /** The user can iterate over elements of grid subset-wise.*/
52 : class UG_API GridSubsetHandler : public ISubsetHandler
53 : {
54 : public:
55 : using ISubsetHandler::assign_subset;
56 :
57 : public:
58 : GridSubsetHandler(uint supportedElements = SHE_ALL);
59 : GridSubsetHandler(Grid& grid, uint supportedElements = SHE_ALL);
60 : /** WARNING: Don't call the copy-constructor from derived classes,
61 : * Since it calls virtual methods.*/
62 : GridSubsetHandler(const GridSubsetHandler& sh);
63 : ~GridSubsetHandler();
64 :
65 : GridSubsetHandler& operator = (const GridSubsetHandler& sh);
66 : GridSubsetHandler& operator = (const ISubsetHandler& sh);
67 :
68 : void assign_grid(Grid* grid);
69 : void assign_grid(Grid& grid);
70 :
71 : ////////////////////////////////////////////////
72 : // implementation of public virtual methdos of ISubsetHandler.
73 : /// assigns a vertex to a subset.
74 : /** If the subset doesn't already exist, it will be created.*/
75 : void assign_subset(Vertex* elem, int subsetIndex);
76 :
77 : /// assigns an edge to a subset.
78 : /** If the subset doesn't already exist, it will be created.*/
79 : void assign_subset(Edge* elem, int subsetIndex);
80 :
81 : /// assigns a face to a subset.
82 : /** If the subset doesn't already exist, it will be created.*/
83 : void assign_subset(Face* elem, int subsetIndex);
84 :
85 : /// assigns a volume to a subset.
86 : /** If the subset doesn't already exist, it will be created.*/
87 : void assign_subset(Volume* elem, int subsetIndex);
88 :
89 : ////////////////////////////////////////////////
90 : // element-access
91 : /// returns the begin-iterator for the elements of type TElem in the given subset.
92 : /** e.g. begin<Triangle>(0)*/
93 : template <class TElem>
94 : typename geometry_traits<TElem>::iterator
95 : begin(int subsetIndex);
96 :
97 : /// returns the end-iterator for the elements of type TElem in the given subset.
98 : /** e.g. end<Triangle>(0)*/
99 : template <class TElem>
100 : typename geometry_traits<TElem>::iterator
101 : end(int subsetIndex);
102 :
103 : /// returns the begin-iterator for the elements of type TElem in the given subset.
104 : /** e.g. begin<Triangle>(0)*/
105 : template <class TElem>
106 : typename geometry_traits<TElem>::const_iterator
107 : begin(int subsetIndex) const;
108 :
109 : /// returns the end-iterator for the elements of type TElem in the given subset.
110 : /** e.g. end<Triangle>(0)*/
111 : template <class TElem>
112 : typename geometry_traits<TElem>::const_iterator
113 : end(int subsetIndex) const;
114 :
115 : /// returns the number of elements in the given subset
116 : template <class TElem>
117 : uint num_elements(int subsetIndex) const;
118 :
119 : /// returns the total number of elements
120 : template <class TElem>
121 : uint num() const;
122 :
123 : /// returns the number of elements in the given subset
124 : template <class TElem>
125 : uint num(int subsetIndex) const;
126 :
127 : /// returns true if the subset-handler contains no elements of the given type.
128 : template <class TElem> inline
129 : bool empty() const;
130 :
131 : /// returns true if the subset-handler contains no elements at all.
132 : inline bool empty() const;
133 :
134 : template <class TElem> inline
135 : bool empty(int subsetIndex) const;
136 :
137 : /// returns true if the subset-handler contains no elements at all.
138 : inline bool empty(int subsetIndex) const;
139 :
140 : /// removes all elements of type TElem from the specified subset.
141 : template <class TElem>
142 : void clear_subset_elements(int subsetIndex);
143 :
144 : // geometric-object-collection
145 : virtual GridObjectCollection
146 : get_grid_objects_in_subset(int subsetIndex) const;
147 :
148 : // multi-level-geometric-object-collection
149 : GridObjectCollection
150 : get_grid_objects() const;
151 :
152 : /// collects all vertices that are in the given subset.
153 : /** Please consider using begin and end methods instead.
154 : * If subset -1 is specified, the method has compexity O(n), where n is the number
155 : * of vertices in the underlying grid.
156 : * \returns number of collected elements.
157 : * \sa begin, end*/
158 : //virtual size_t collect_subset_elements(std::vector<Vertex*>& vrtsOut, int subsetIndex) const;
159 :
160 : /// collects all edges that are in the given subset.
161 : /** Please consider using begin and end methods instead.
162 : * If subset -1 is specified, the method has compexity O(n), where n is the number
163 : * of edges in the underlying grid.
164 : * \returns number of collected elements.
165 : * \sa begin, end*/
166 : //virtual size_t collect_subset_elements(std::vector<Edge*>& edgesOut, int subsetIndex) const;
167 :
168 : /// collects all faces that are in the given subset.
169 : /** Please consider using begin and end methods instead.
170 : * If subset -1 is specified, the method has compexity O(n), where n is the number
171 : * of faces in the underlying grid.
172 : * \returns number of collected elements.
173 : * \sa begin, end*/
174 : //virtual size_t collect_subset_elements(std::vector<Face*>& facesOut, int subsetIndex) const;
175 :
176 : /// collects all volumes that are in the given subset.
177 : /** Please consider using begin and end methods instead.
178 : * If subset -1 is specified, the method has compexity O(n), where n is the number
179 : * of volumes in the underlying grid.
180 : * \returns number of collected elements.
181 : * \sa begin, end*/
182 : //virtual size_t collect_subset_elements(std::vector<Volume*>& volsOut, int subsetIndex) const;
183 :
184 : /// returns true if the subset contains vertices
185 0 : virtual bool contains_vertices(int subsetIndex) const {return num<Vertex>(subsetIndex) > 0;}
186 :
187 : /// returns true if the subset contains edges
188 0 : virtual bool contains_edges(int subsetIndex) const {return num<Edge>(subsetIndex) > 0;}
189 :
190 : /// returns true if the subset contains faces
191 0 : virtual bool contains_faces(int subsetIndex) const {return num<Face>(subsetIndex) > 0;}
192 :
193 : /// returns true if the subset contains volumes
194 0 : virtual bool contains_volumes(int subsetIndex) const {return num<Volume>(subsetIndex) > 0;}
195 :
196 : /// only for debug purposes
197 : template <class TElem>
198 : bool perform_self_tests();
199 :
200 : ////////////////////////////////////////////////
201 : // for compatibility with MGSubsetHandler
202 : /// returns number of levels (always 1)
203 : /** only for compatibility reasons with MGSubsetHandler.*/
204 : uint num_levels() const {return 1;}
205 :
206 : /// returns the begin-iterator for the elements of type TElem in the given subset.
207 : /** only for compatibility reasons with MGSubsetHandler.
208 : * second argument is ignored.
209 : * use i.e. as follows: begin<Triangle>(0, 0)*/
210 : template <class TElem>
211 : typename geometry_traits<TElem>::const_iterator
212 : begin(int subsetIndex, size_t) const {return begin<TElem>(subsetIndex);}
213 :
214 : /// returns the end-iterator for the elements of type TElem in the given subset.
215 : /** only for compatibility reasons with MGSubsetHandler.
216 : * second argument is ignored.
217 : * use i.e. as follows: end<Triangle>(0, 0)*/
218 : template <class TElem>
219 : typename geometry_traits<TElem>::const_iterator
220 : end(int subsetIndex, size_t) const {return end<TElem>(subsetIndex);}
221 :
222 : /// returns the number of elements in the given subset
223 : /** only for compatibility reasons with MGSubsetHandler.
224 : * second argument is ignored.*/
225 : template <class TElem>
226 : uint num_elements(int subsetIndex, size_t) const {return num_elements<TElem>();}
227 :
228 : /// returns the number of elements in the given subset
229 : /** only for compatibility reasons with MGSubsetHandler.
230 : * second argument is ignored.*/
231 : template <class TElem>
232 : uint num(int subsetIndex, size_t) const {return num<TElem>();}
233 :
234 :
235 : /// perform cleanup
236 : virtual void grid_to_be_destroyed(Grid* grid);
237 :
238 : protected:
239 : using ISubsetHandler::AttachedVertexList;
240 : using ISubsetHandler::AttachedEdgeList;
241 : using ISubsetHandler::AttachedFaceList;
242 : using ISubsetHandler::AttachedVolumeList;
243 :
244 : using ISubsetHandler::VertexSectionContainer;
245 : using ISubsetHandler::EdgeSectionContainer;
246 : using ISubsetHandler::FaceSectionContainer;
247 : using ISubsetHandler::VolumeSectionContainer;
248 :
249 : /// returns the number of subsets in the local list
250 0 : inline uint num_subsets_in_list() const {return (uint)m_subsets.size();}
251 :
252 : /// detaches all attached data.
253 : void detach_data();
254 :
255 : ////////////////////////////////////////////////
256 : // implementation of protected virtual methdos of ISubsetHandler.
257 : /// erases the subsets. Doesn't alter any indices.
258 : virtual void erase_subset_lists();
259 :
260 : /// non-virtual implementation of erase_subset_lists. Callable from destructor
261 : void erase_subset_lists_impl();
262 :
263 : /// clears the element lists in the given subset. Does not alter any indices.
264 : virtual void clear_subset_lists(int index);
265 :
266 : /// changes the subset-indices of all elements int the subset.
267 : /** WARNING: subsets are not automatically changed accordingly.
268 : * After termination Subset-Indices and Subset-Infos/iterators are asynchronous.
269 : * Make sure to change subset-infos and iterators accordingly.*/
270 : virtual void change_subset_indices(int indOld, int indNew);
271 :
272 :
273 : /// add a subset
274 : void add_required_subset_lists(int maxIndex);
275 :
276 : /// erases the subset but does not touch the subset-indices.
277 : void erase_subset_lists(int index);
278 :
279 : /// swaps the subsets but does not touch the subset-indices.
280 : void swap_subset_lists(int ind1, int ind2);
281 :
282 : /// moves the subset but does not touch the subset-indices.
283 : void move_subset_lists(int indexFrom, int indexTo);
284 :
285 : /// join the subset-lists but do not touch the subset-indices.
286 : void join_subset_lists(int target, int src1, int src2);
287 :
288 : /// this method is called by ISubsetHandler when attachment_support has been enabled.
289 : //void register_subset_elements_at_pipe();
290 :
291 : ////////////////////////////////////////////////
292 : // protected helper methods
293 : /// a helper method for the public assign_subset methods.
294 : template<class TElem> inline
295 : void assign_subset_impl(TElem* elem, int subsetIndex);
296 :
297 : /// helper for change_subset_indices
298 : template<class TElem>
299 : void change_elem_subset_indices(int indOld, int indNew);
300 :
301 : /// helper for collect_subset_elements
302 : //template <class TElem>
303 : //size_t collect_subset_elements_impl(std::vector<TElem*>& elemsOut, int subsetIndex) const;
304 :
305 : /// removes attachments
306 : void cleanup();
307 :
308 : /// returns the iterator at which the given element lies in the section container
309 : /** This method may only be called if the element is in a subset != -1.
310 : * \{
311 : */
312 : inline VertexSectionContainer::iterator
313 0 : get_list_iterator(Vertex* o)
314 : {
315 : assert((get_subset_index(o) >= 0) && "invalid subset.");
316 0 : return section_container<Vertex>(get_subset_index(o)).
317 0 : get_container().get_iterator(o);
318 : }
319 :
320 : inline EdgeSectionContainer::iterator
321 0 : get_list_iterator(Edge* o)
322 : {
323 : assert((get_subset_index(o) >= 0) && "invalid subset.");
324 0 : return section_container<Edge>(get_subset_index(o)).
325 0 : get_container().get_iterator(o);
326 : }
327 :
328 : inline FaceSectionContainer::iterator
329 0 : get_list_iterator(Face* o)
330 : {
331 : assert((get_subset_index(o) >= 0) && "invalid subset.");
332 0 : return section_container<Face>(get_subset_index(o)).
333 0 : get_container().get_iterator(o);
334 : }
335 :
336 : inline VolumeSectionContainer::iterator
337 0 : get_list_iterator(Volume* o)
338 : {
339 : assert((get_subset_index(o) >= 0) && "invalid subset.");
340 0 : return section_container<Volume>(get_subset_index(o)).
341 0 : get_container().get_iterator(o);
342 : }
343 : /** \} */
344 :
345 : /// returns the section container for the given type, subset and level
346 : template <class TElem> inline
347 : typename Grid::traits<TElem>::SectionContainer&
348 : section_container(int si);
349 :
350 : /// returns the const section container for the given type, subset and level
351 : template <class TElem> inline
352 : const typename Grid::traits<TElem>::SectionContainer&
353 : section_container(int si) const;
354 :
355 : protected:
356 : struct Subset
357 : {
358 : VertexSectionContainer m_vertices;
359 : EdgeSectionContainer m_edges;
360 : FaceSectionContainer m_faces;
361 : VolumeSectionContainer m_volumes;
362 : };
363 :
364 : typedef std::vector<Subset*> SubsetVec;
365 :
366 : protected:
367 : SubsetVec m_subsets;
368 : // we use a shared attachment for the entry-lists of all section containers
369 : AttachedVertexList::AEntry m_aSharedEntryVRT;
370 : AttachedEdgeList::AEntry m_aSharedEntryEDGE;
371 : AttachedFaceList::AEntry m_aSharedEntryFACE;
372 : AttachedVolumeList::AEntry m_aSharedEntryVOL;
373 : };
374 :
375 :
376 : typedef GridSubsetHandler SubsetHandler;
377 :
378 : /** \} */
379 :
380 : }// end of namespace
381 :
382 : // include implementation
383 : #include "subset_handler_grid_impl.hpp"
384 :
385 : #endif
|