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__UG__LIB_GRID__TOOLS__SURFACE_VIEW__
34 : #define __H__UG__LIB_GRID__TOOLS__SURFACE_VIEW__
35 :
36 : #ifdef UG_PARALLEL
37 : #include "lib_grid/parallelization/distributed_grid.h"
38 : #endif
39 :
40 : #include "lib_grid/multi_grid.h"
41 : #include "lib_grid/tools/grid_level.h"
42 : #include "subset_handler_multi_grid.h"
43 : #include "lib_grid/algorithms/attachment_util.h"
44 : #include "common/util/flags.h"
45 :
46 : namespace ug{
47 :
48 : /** \ingroup lib_grid_tools
49 : * \{ */
50 :
51 : /// Represents the surface view of a multi-grid hierarchy.
52 : /** The surface of a multi-grid hierarchy consists of all elements, which
53 : * do not have children.
54 : * The surface view allows to iterate over the subsets of such a surface.
55 : * The surface_begin(...) and surface_end(...) methods even allow
56 : * to ignore all levels above a specified level, resulting in a new surface-view
57 : * in which only surface elements up to the specified level and the elements in
58 : * the specified level are regarded as surface-view-elements.
59 : */
60 : class SurfaceView
61 : {
62 : public:
63 : /**
64 : * Byte-Constants, that identify the SurfaceState of an grid-object.
65 : *
66 : * Every grid-object is in exactly one SurfaceState. In addition some
67 : * combinations of the states are named for an easier usage.
68 : *
69 : * IMPORTANT: The order of the byte-flags is currently crucial. Do not
70 : * change them. See ComPol_GatherSurfaceStates.
71 : */
72 : enum SurfaceConstants{
73 : // each grid-object has exactly on of these states (begin)
74 : MG_SHADOW_PURE = 1, ///< full-covered (inner)
75 : MG_SURFACE_PURE = 1 << 1, ///< surface, i.e., without children (inner)
76 : MG_SURFACE_RIM = 1 << 2, ///< surface, i.e., without children (at rim)
77 : MG_SHADOW_RIM_COPY = 1 << 3, ///< covered (at rim) with identical child
78 : MG_SHADOW_RIM_NONCOPY = 1 << 4, ///< covered (at rim) with non-identical child(ren)
79 : // each grid-object has exactly on of these states (end)
80 :
81 : // combo-states with flags as in multi-grid (begin)
82 : MG_SHADOW_RIM = MG_SHADOW_RIM_COPY | MG_SHADOW_RIM_NONCOPY, //!< all rim-shadows
83 : MG_SHADOW = MG_SHADOW_RIM | MG_SHADOW_PURE, //!< all shadows
84 : MG_SURFACE = MG_SURFACE_PURE | MG_SURFACE_RIM, //!< all surface
85 : MG_ALL_BUT_SHADOW_COPY = MG_SURFACE | MG_SHADOW_RIM_NONCOPY, //!< surface + rim-non-copy-shadows
86 : MG_ALL = MG_SURFACE | MG_SHADOW_RIM, //!< all (except pure-shadow)
87 : // combo-states with flags as in multi-grid (end)
88 :
89 : TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE = 1 << 5, //! pseudo-state
90 :
91 : // combo-states with flags as in level-view (begin)
92 : SHADOW_PURE = MG_SHADOW_PURE | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
93 : SURFACE_PURE = MG_SURFACE_PURE | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
94 : SURFACE_RIM = MG_SURFACE_RIM | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
95 : SHADOW_RIM_COPY = MG_SHADOW_RIM_COPY | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
96 : SHADOW_RIM_NONCOPY = MG_SHADOW_RIM_NONCOPY | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
97 :
98 : SHADOW_RIM = MG_SHADOW_RIM | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
99 : SHADOW = MG_SHADOW | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
100 : SURFACE = MG_SURFACE | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
101 : ALL_BUT_SHADOW_COPY = MG_ALL_BUT_SHADOW_COPY | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE,
102 : ALL = MG_ALL | TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE
103 : // combo-states with flags as in level-view (end)
104 : };
105 : typedef Flag<SurfaceConstants, byte, SS_NONE> SurfaceState;
106 : typedef Attachment<SurfaceState> ASurfaceState;
107 :
108 : public:
109 : SurfaceView(SmartPtr<MGSubsetHandler> spMGSH,
110 : bool adaptiveMG = true);
111 :
112 : ~SurfaceView();
113 :
114 : /// returns underlying subset handler
115 : inline SmartPtr<MGSubsetHandler> subset_handler();
116 :
117 : /// returns underlying subset handler
118 : inline ConstSmartPtr<MGSubsetHandler> subset_handler() const;
119 :
120 : /// returns if multigrid is adaptive
121 : inline bool is_adaptive() const;
122 :
123 : /// returns if the element is contained in the surface view
124 : template <class TGeomObj>
125 : inline bool is_contained(TGeomObj* obj, const GridLevel& gl,
126 : SurfaceState validStates = ALL) const;
127 :
128 : /// returns the surface states, when considered as part of grid level
129 : template <class TElem>
130 : SurfaceState surface_state(TElem* elem, const GridLevel& gl) const;
131 :
132 : /// returns if the element is ghost
133 : /** ghost elements are vertical masters that are in no other interfaces.*/
134 : template <class TGeomObj>
135 : inline bool is_ghost(TGeomObj* obj) const;
136 :
137 : /// returns if the element is shadowed and thus not contained in the surface view
138 : /** A shadowed element has a child and at least one adjacent element which is
139 : * a surface element
140 : * \sa SurfaceView::is_surface_element, SurfaceView::is_shadowing*/
141 : template <class TGeomObj>
142 : inline bool is_shadowed(TGeomObj* obj) const;
143 :
144 : /// returns true if the given element is a shadowing element
145 : /** An element is considered to be shadowing if it is the child of a
146 : * shadowed element. Not that in a distributed grid, this can be true even
147 : * if the element has no parent on the local process.
148 : * \sa SurfaceView::is_shadowed, SurfaceView::is_surface_element*/
149 : template <class TGeomObj>
150 : inline bool is_shadowing(TGeomObj* obj) const;
151 :
152 : /// refresh_surface_states must be called after a grid change
153 : void refresh_surface_states();
154 :
155 : /// returns an or combination of current surface states
156 : /** Please use the methods is_surface_element, is_shadowed and is_shadowing
157 : * instead of this method.
158 : * The only reason it is publicly accessible is for debugging reasons.
159 : *
160 : * \note a protected non-const version exists, which returns a reference to the state.*/
161 : template <class TElem>
162 0 : SurfaceState surface_state(TElem* elem) const {return m_aaSurfState[elem];}
163 :
164 : /// returns the adjacent elements w.r.t. the grid level
165 : template <typename TElem, typename TBaseElem>
166 : void collect_associated(std::vector<TBaseElem*>& vAssElem,
167 : TElem* elem,
168 : const GridLevel& gl,
169 : bool clearContainer = true) const;
170 :
171 : public:
172 : template <class TElem> class SurfaceViewElementIterator;
173 : template <class TElem> class ConstSurfaceViewElementIterator;
174 :
175 : /// Iterator to traverse the surface of a multi-grid hierarchy
176 : template <class TElem>
177 0 : class SurfaceViewElementIterator
178 : {
179 : public:
180 : SurfaceViewElementIterator();
181 :
182 : private:
183 : typedef SurfaceViewElementIterator<TElem> this_type;
184 : typedef TElem* TValue;
185 :
186 : friend class SurfaceView;
187 : friend class ConstSurfaceViewElementIterator<TElem>;
188 :
189 : SurfaceViewElementIterator(bool start,
190 : SurfaceView* surfView,
191 : const GridLevel& gl,
192 : SurfaceState validStates,
193 : int si = -1);
194 :
195 : public:
196 0 : this_type operator ++() {increment(); return *this;}
197 : this_type operator ++(int unused) {this_type i = *this; increment(); return i;}
198 :
199 : bool operator ==(const this_type& iter) const {return equal(iter);}
200 : bool operator !=(const this_type& iter) const {return !equal(iter);}
201 :
202 : TValue operator *() {return dereference();}
203 :
204 : private:
205 : /// returns if this iterator equals another
206 : inline bool equal(SurfaceViewElementIterator<TElem> const& other) const;
207 :
208 : /// returns if valid element, i.e. contained in iterator loop
209 : template <class TGeomObj>
210 : inline bool is_contained(TGeomObj* obj) const;
211 :
212 : /// returns next valid iterator
213 : void increment();
214 :
215 : /// returns begin-iterator of next non-empty section, returns false if not available
216 : bool increment_section();
217 :
218 : /// dereference
219 : inline TValue dereference() const;
220 :
221 : private:
222 : SurfaceView* m_pSurfView;
223 : GridLevel m_gl;
224 : SurfaceState m_validStates;
225 : int m_fromSI;
226 : int m_toSI;
227 : int m_si;
228 : int m_topLvl;
229 : int m_lvl;
230 : typename geometry_traits<TElem>::iterator m_elemIter;
231 : typename geometry_traits<TElem>::iterator m_iterEndSection;
232 : };
233 :
234 : /// Const iterator to traverse the surface of a multi-grid hierarchy
235 : template <class TElem>
236 0 : class ConstSurfaceViewElementIterator
237 : {
238 : public:
239 : ConstSurfaceViewElementIterator();
240 :
241 : ConstSurfaceViewElementIterator(const SurfaceViewElementIterator<TElem>& iter);
242 :
243 : private:
244 : typedef ConstSurfaceViewElementIterator<TElem> this_type;
245 : // \todo: should return const TElem*
246 : typedef TElem* TValue;
247 : //typedef const TElem* TValue;
248 :
249 : friend class SurfaceView;
250 :
251 : ConstSurfaceViewElementIterator(bool start,
252 : const SurfaceView* surfView,
253 : const GridLevel& gl,
254 : SurfaceState validStates,
255 : int si = -1);
256 :
257 : public:
258 0 : this_type operator ++() {increment(); return *this;}
259 0 : this_type operator ++(int unused) {this_type i = *this; increment(); return i;}
260 :
261 : bool operator ==(const this_type& iter) const {return equal(iter);}
262 : bool operator !=(const this_type& iter) const {return !equal(iter);}
263 :
264 : TValue operator *() {return dereference();}
265 :
266 : private:
267 : /// returns if this iterator equals another
268 : inline bool equal(ConstSurfaceViewElementIterator<TElem> const& other) const;
269 :
270 : /// returns if valid element, i.e. contained in iterator loop
271 : template <class TGeomObj>
272 : inline bool is_contained(TGeomObj* obj) const;
273 :
274 : /// returns next valid iterator
275 : void increment();
276 :
277 : /// returns begin-iterator of next non-empty section, returns false if not available
278 : bool increment_section();
279 :
280 : /// dereference
281 : inline TValue dereference() const;
282 :
283 : private:
284 : const SurfaceView* m_pSurfView;
285 : GridLevel m_gl;
286 : SurfaceState m_validStates;
287 : int m_fromSI;
288 : int m_toSI;
289 : int m_si;
290 : int m_topLvl;
291 : int m_lvl;
292 : typename geometry_traits<TElem>::const_iterator m_elemIter;
293 : typename geometry_traits<TElem>::const_iterator m_iterEndSection;
294 : };
295 :
296 : public:
297 : template <class TElem>
298 : struct traits{
299 : typedef SurfaceViewElementIterator<TElem> iterator;
300 : typedef ConstSurfaceViewElementIterator<TElem> const_iterator;
301 : };
302 :
303 : /// iterators of grid level
304 : /// \{
305 : template <class TElem>
306 : typename traits<TElem>::iterator
307 : begin(int si, const GridLevel& gl, SurfaceState validStates);
308 :
309 : template <class TElem>
310 : typename traits<TElem>::iterator
311 : end(int si, const GridLevel& gl, SurfaceState validStates);
312 :
313 : template <class TElem>
314 : typename traits<TElem>::const_iterator
315 : begin(int si, const GridLevel& gl, SurfaceState validStates) const;
316 :
317 : template <class TElem>
318 : typename traits<TElem>::const_iterator
319 : end(int si, const GridLevel& gl, SurfaceState validStates) const;
320 :
321 : template <class TElem>
322 : typename traits<TElem>::iterator
323 : begin(const GridLevel& gl, SurfaceState validStates);
324 :
325 : template <class TElem>
326 : typename traits<TElem>::iterator
327 : end(const GridLevel& gl, SurfaceState validStates);
328 :
329 : template <class TElem>
330 : typename traits<TElem>::const_iterator
331 : begin(const GridLevel& gl, SurfaceState validStates) const;
332 :
333 : template <class TElem>
334 : typename traits<TElem>::const_iterator
335 : end(const GridLevel& gl, SurfaceState validStates) const;
336 : /// \}
337 :
338 : private:
339 : /// returns true if the element is a surface element locally
340 : /** This method disregards possible copies of the given element on other processes.
341 : * The method is used during surface-state computation in refresh_surface_states.
342 : * The method returns false if the given element has children or if it is
343 : * contained in a vertical master interface.*/
344 : template <class TElem>
345 : bool is_local_surface_view_element(TElem* elem);
346 :
347 : /// only call for elements of highest dimension
348 : template <class TElem>
349 : void refresh_surface_states();
350 :
351 : /// recursively marks sides and sides of sides as surface or shadow
352 : /** This method is used during refresh_surface_states to assign surface
353 : * states to sides of surface elements.
354 : * Make sure that all elements in lower levels have already been processed!*/
355 : template <class TElem, class TSide>
356 : void mark_sides_as_surface_or_shadow(TElem* elem,
357 : byte surfaceState = MG_SURFACE_PURE);
358 :
359 : template <class TElem>
360 : void mark_shadowing(bool markSides = false);
361 :
362 : /// adjusts surface states in a parallel environment
363 : template <class TElem>
364 : void adjust_parallel_surface_states();
365 :
366 : template <class TElem>
367 0 : SurfaceState& surface_state(TElem* elem) {return m_aaSurfState[elem];}
368 :
369 : template <class TElem>
370 : bool is_vmaster(TElem* elem) const;
371 :
372 : private:
373 : SmartPtr<MGSubsetHandler> m_spMGSH;
374 : bool m_adaptiveMG;
375 : MultiGrid* m_pMG;
376 : DistributedGridManager* m_distGridMgr;
377 : ASurfaceState m_aSurfState;
378 : MultiElementAttachmentAccessor<ASurfaceState> m_aaSurfState;
379 : };
380 :
381 : /** \} */
382 :
383 : }// end of namespace
384 :
385 :
386 : ////////////////////////////////////////
387 : // include implementation
388 : #include "surface_view_impl.hpp"
389 :
390 : #endif
|