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