Line data Source code
1 : /*
2 : * Copyright (c) 2011-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__REFINER_INTERFACE__
34 : #define __H__UG__REFINER_INTERFACE__
35 :
36 : #include <string>
37 : #include "projectors/refinement_projector.h"
38 :
39 : namespace ug
40 : {
41 : /// \addtogroup lib_grid_algorithms_refinement
42 : /// @{
43 :
44 : /// refinement-marks allow to specify how an element shall be processed during refinement.
45 : // Make sure not to use refinement marks with a value of 128 or higher! Those
46 :
47 : ///< Fully refines an element and all associated sides and edges
48 : enum RefinementMark{
49 : RM_NONE = 0, ///< no refinement is performed
50 : RM_CLOSURE = 1, ///< Refines elements according to associated marked edges
51 : RM_COPY = RM_CLOSURE, ///< DEPRECATED. Use RM_CLOSURE or RM_LOCAL with localMark = 0 instead.
52 : RM_ANISOTROPIC = RM_CLOSURE, ///< DEPRECATED. Use RM_CLOSURE instead.
53 : RM_LOCAL = 1 << 1, ///< Refines elements according to a local refinement mark (use 'mark_local')
54 : RM_FULL = 1 << 2, ///< Fully refines an element and all associated sides and edges
55 : RM_REFINE = RM_FULL, ///< DEPRECATED. Use RM_FULL instead.
56 : RM_COARSEN = 1 << 3, ///< the element is coarsened (only valid for adaptive multi-grid refinement)
57 : RM_DUMMY = 1 << 4, ///< used internally during mark-adjustment
58 : RM_MAX ///< the highest constant in RefinementMark. Should always be smaller than 128!
59 : };
60 :
61 : /// The refiner interface allows to mark elements for refinement and to call refine.
62 : /** A refiner always operates on a grid. A grid thus has to be assigned
63 : * before refinement starts. Please take a look at the specializations
64 : * of IRefiner, for more information.
65 : */
66 : class IRefiner
67 : {
68 : public:
69 0 : IRefiner(SPRefinementProjector projector = SPNULL) :
70 0 : m_msgIdAdaption(-1), m_projector(projector),
71 0 : m_adaptionIsActive(false), m_debuggingEnabled(false) {}
72 :
73 0 : virtual ~IRefiner() {}
74 :
75 0 : void set_projector(SPRefinementProjector projector)
76 0 : {m_projector = projector;}
77 :
78 : SPRefinementProjector projector()
79 : {return m_projector;}
80 :
81 : /// DEPRECIATED! Use grid(). Has to return the associated grid. Pure virtual
82 : virtual Grid* get_associated_grid() = 0;
83 : /// Returns the grid associated with the refiner
84 : /** Pure virtual. Specify this method in derived classes!*/
85 : virtual Grid* grid() = 0;
86 :
87 : /// clears all marks. Default implementation is empty
88 0 : virtual void clear_marks() {}
89 :
90 : /// returns whether the refiner is able to perform adaptive refinement
91 : /** pure virtual!*/
92 : virtual bool adaptivity_supported() const = 0;
93 :
94 : /// returns true, if the refiner supports coarsening.
95 : /** pure virtual!*/
96 : virtual bool coarsening_supported() const = 0;
97 :
98 : /// returns true, if the refiner supports local marks.
99 0 : virtual bool local_marks_supported() const {return false;}
100 :
101 : /// Marks an element for refinement. Default implementation is empty
102 : /** \{ */
103 0 : virtual bool mark(Vertex* v, RefinementMark refMark = RM_REFINE) {return false;}
104 0 : virtual bool mark(Edge* e, RefinementMark refMark = RM_REFINE) {return false;}
105 0 : virtual bool mark(Face* f, RefinementMark refMark = RM_REFINE) {return false;}
106 0 : virtual bool mark(Volume* v, RefinementMark refMark = RM_REFINE) {return false;}
107 : /** \} */
108 :
109 : /// marks the specified geometric object
110 : /** The default implementation casts the object to a more concrete type
111 : * (Vertex, Edge, Face, Volume) and calls the appropriate mark method.*/
112 : virtual bool mark(GridObject* o, RefinementMark refMark = RM_REFINE);
113 :
114 :
115 : template <class TElem>
116 : inline bool marked_closure(TElem* elem) const
117 : {
118 0 : return (get_mark(elem) == RM_CLOSURE);
119 : }
120 :
121 : template <class TElem>
122 : inline bool marked_local(TElem* elem) const
123 : {
124 0 : return (get_mark(elem) == RM_LOCAL);
125 : }
126 :
127 : template <class TElem>
128 : inline bool marked_full(TElem* elem) const
129 : {
130 0 : return (get_mark(elem) == RM_FULL);
131 : }
132 :
133 : /// Marks a face or volume for local refinement.
134 : /** The passed mark is an or combination. If the i-th edge of the element
135 : * shall be refined, it should hold true: 'mark & 1<<i != 0'.
136 : * The passed element will also receive the RM_LOCAL flag.
137 : * \note local-marks differ from mark(e, RM_CLOSURE). The former will
138 : * refine an element according to the marks of associated edges.
139 : * Elements marked with mark_local, however, will only be refined
140 : * according to their local mark.
141 : * \{ */
142 0 : virtual void mark_local(Face* e, int mark) {UG_THROW("mark_local not supported by this refiner!");}
143 0 : virtual void mark_local(Volume* e, int mark) {UG_THROW("mark_local not supported by this refiner!");}
144 : /** \} */
145 :
146 : /// returns the local mark of the specified face or volume.
147 : /** If the i-th edge of the element shall be refined, it holds true:
148 : * 'get_local_mark(e) & 1<<i != 0'
149 : * \{ */
150 0 : virtual int get_local_mark(Face* e) const {return 0;}
151 0 : virtual int get_local_mark(Volume* e) const {return 0;}
152 : /** \} */
153 :
154 :
155 : /// returns the local mark of the specified edge of the given face
156 : /** Note that this is not necessarily the mark of the edge itself. Instead
157 : * the mark of the edge as induced by the local mark of the face is returned.
158 : * The method also considers marks RM_FULL and RM_CLOSURE.*/
159 : int get_local_edge_mark(Face* f, Edge* e) const;
160 :
161 : /// returns the local mark of the specified edge of the given volume
162 : /** Note that this is not necessarily the mark of the edge itself. Instead
163 : * the mark of the edge as induced by the local mark of the volume is returned.
164 : * The method also considers marks RM_FULL and RM_CLOSURE.*/
165 : int get_local_edge_mark(Volume* vol, Edge* e) const;
166 :
167 : /// returns the local mark of the specified face of the given volume
168 : /** Note that this is not necessarily the mark of the face itself. Instead
169 : * the mark of the face as induced by the local mark of the volume is returned.
170 : * The method also considers marks RM_FULL and RM_CLOSURE.*/
171 : int get_local_face_mark(Volume* vol, Face* f) const;
172 :
173 :
174 : /// marks the neighborhood of currently marked elements.
175 : /** In each step direct neighbors of currently marked elements are selected.
176 : * The number of iterations thus specifies the width of the neighborhood which
177 : * will be marked.
178 : * Calls mark_neighborhood(numIterations, RM_NONE, false)*/
179 0 : void mark_neighborhood(size_t numIterations)
180 0 : {mark_neighborhood(numIterations, RM_NONE, false);}
181 :
182 : /// marks the neighborhood of currently marked elements.
183 : /** In each step direct neighbors of currently marked elements are also marked.
184 : * You may specify the refinement mark that will be applied to newly mared elements
185 : * - elements which already were marked will be ignored.
186 : * By passing RM_NONE as refMark, the refinement-mark will be derived from
187 : * neighbored elements.
188 : * If sideNbrsOnly is set to true, only elements which are connected to
189 : * sides of marked elements are also marked. Otherwise all elements which are
190 : * connected to vertices of marked elements are marked.*/
191 0 : virtual void mark_neighborhood(
192 : size_t numIterations,
193 : RefinementMark refMark,
194 0 : bool sideNbrsOnly) {}
195 :
196 : /// Returns the mark of a given element. Default returns RM_REFINE
197 : /** \{ */
198 0 : virtual RefinementMark get_mark(Vertex* v) const {return RM_REFINE;}
199 0 : virtual RefinementMark get_mark(Edge* e) const {return RM_REFINE;}
200 0 : virtual RefinementMark get_mark(Face* f) const {return RM_REFINE;}
201 0 : virtual RefinementMark get_mark(Volume* v) const {return RM_REFINE;}
202 : /** \} */
203 :
204 : /// returns the mark of the specified geometric object
205 : /** The default implementation casts the object to a more concrete type
206 : * (Vertex, Edge, Face, Volume) and calls the appropriate get_mark method.*/
207 : virtual RefinementMark get_mark(GridObject* o) const;
208 :
209 : /// marks all elements between iterBegin and iterEnd.
210 : /** the value-type of TIterator has to be a pointer to a type derived
211 : * from either Edge, Face or Volume.*/
212 : template <class TIterator>
213 0 : void mark(const TIterator& iterBegin, const TIterator& iterEnd,
214 : RefinementMark refMark = RM_REFINE)
215 : {
216 : TIterator iter = iterBegin;
217 0 : while(iter != iterEnd){
218 0 : mark(*iter, refMark);
219 0 : ++iter;
220 : }
221 0 : }
222 :
223 :
224 : /// notifies all listeners of the associated message-hub, that adaption begins / ends.
225 : /** While this message is not important to the refiner itself, it may be important
226 : * to listeners of the associated grid's message-hub.
227 : * \{ */
228 : void adaption_begins();
229 : void adaption_ends();
230 : /** \} */
231 :
232 : /// Performs refinement on the marked elements.
233 : /** internally calls the virtual method 'perform_refinement'*/
234 : void refine();
235 :
236 : /// Performs coarsening on the elements marked RM_COARSEN.
237 : /** Note that coarsening is not supported by all refiners. Normally only
238 : * MultiGrid-Refiner do support coarsening.
239 : *
240 : * coarsen returns false, if no elements have been coarsened, true if at
241 : * least one has been coarsened.
242 : *
243 : * Internally calls the virtual method 'perform_coarsening'
244 : */
245 : bool coarsen();
246 :
247 :
248 : /// returns the number of (globally) marked edges on all levels of the hierarchy
249 : size_t num_marked_edges(std::vector<int>& numMarkedEdgesOut);
250 : /// returns the number of (globally) marked faces on all levels of the hierarchy
251 : size_t num_marked_faces(std::vector<int>& numMarkedFacesOut);
252 : /// returns the number of (globally) marked volumes on all levels of the hierarchy
253 : size_t num_marked_volumes(std::vector<int>& numMarkedVolsOut);
254 : /// returns the number of (globally) marked grid-objects of highest dimension
255 : size_t num_marked_elements(std::vector<int>& numMarkedElemsOut);
256 :
257 : /// returns the number of (globally) marked edges on all levels of the hierarchy
258 0 : size_t num_marked_edges() {std::vector<int> t; return num_marked_edges(t);}
259 : /// returns the number of (globally) marked faces on all levels of the hierarchy
260 0 : size_t num_marked_faces() {std::vector<int> t; return num_marked_faces(t);}
261 : /// returns the number of (globally) marked volumes on all levels of the hierarchy
262 0 : size_t num_marked_volumes() {std::vector<int> t; return num_marked_volumes(t);}
263 : /// returns the number of (globally) marked grid-objects of highest dimension
264 0 : size_t num_marked_elements() {std::vector<int> t; return num_marked_elements(t);}
265 :
266 : /// Writes the associated grid and marks to a file. Pure virtual.
267 : /** Elements should be assigned to subsets depending on their current
268 : * refinement-mark.*/
269 : virtual bool save_marks_to_file(const char* filename) = 0;
270 :
271 : /// sets a filename to which adjusted marks are saved during refinement / coarsening
272 : /** If no filename is set, then no marks are being saved during refinement / coarsening.
273 : * If you want to unset the file, either pass a NULL pointer or an empty string.*/
274 : void set_adjusted_marks_debug_filename(const char* filename);
275 :
276 0 : void enable_debugging(bool enable) {m_debuggingEnabled = enable;}
277 0 : bool debugging_enabled() const {return m_debuggingEnabled;}
278 :
279 : protected:
280 : /// sets the message hub.
281 : /** A message hub is required, since it is used transmit messages regarding
282 : * adaption, refinement and coarsening.*/
283 : void set_message_hub(SPMessageHub msgHub);
284 :
285 : /// called by refine(). Derived classes should implement their refinement algorithm here.
286 : virtual void perform_refinement() = 0;
287 :
288 : /// Called by coarsen(). Derived classes sould implement their coarsen algorithm here.
289 : /** Since the default implementation does not perform coarsening, it returns false.*/
290 0 : virtual bool perform_coarsening() {return false;}
291 :
292 : /// returns the number of locally marked edges on all levels of the hierarchy
293 : virtual void num_marked_edges_local(std::vector<int>& numMarkedEdgesOut) = 0;
294 : /// returns the number of locally marked faces on all levels of the hierarchy
295 : virtual void num_marked_faces_local(std::vector<int>& numMarkedFacesOut) = 0;
296 : /// returns the number of locally marked volumes on all levels of the hierarchy
297 : virtual void num_marked_volumes_local(std::vector<int>& numMarkedVolsOut) = 0;
298 :
299 : protected:
300 : SPMessageHub m_messageHub;
301 : int m_msgIdAdaption;
302 : SPRefinementProjector m_projector;
303 : bool m_adaptionIsActive;
304 : bool m_debuggingEnabled;
305 : std::string m_adjustedMarksDebugFilename;
306 : };
307 :
308 : /// @} // end of add_to_group command
309 :
310 : }// end of namespace
311 :
312 : #endif
|