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 : #include <cassert>
34 : #include "selector_multi_grid.h"
35 : #include "lib_grid/multi_grid.h"
36 :
37 : namespace ug
38 : {
39 :
40 : ////////////////////////////////////////////////////////////////////////
41 0 : MGSelector::MGSelector(uint supportedElements) :
42 : ISelector(supportedElements),
43 : m_aSharedEntryVRT("MGSelector_SharedListEntryVRT"),
44 : m_aSharedEntryEDGE("MGSelector_SharedListEntryEDGE"),
45 : m_aSharedEntryFACE("MGSelector_SharedListEntryFACE"),
46 0 : m_aSharedEntryVOL("MGSelector_SharedListEntryVOL")
47 : {
48 0 : m_pMultiGrid = NULL;
49 0 : }
50 :
51 0 : MGSelector::MGSelector(MultiGrid& grid, uint supportedElements) :
52 0 : ISelector(supportedElements), m_pMultiGrid(NULL),
53 : m_aSharedEntryVRT("MGSelector_SharedListEntryVRT"),
54 : m_aSharedEntryEDGE("MGSelector_SharedListEntryEDGE"),
55 : m_aSharedEntryFACE("MGSelector_SharedListEntryFACE"),
56 0 : m_aSharedEntryVOL("MGSelector_SharedListEntryVOL")
57 : {
58 0 : assign_grid(&grid);
59 0 : }
60 :
61 0 : MGSelector::~MGSelector()
62 : {
63 0 : cleanup();
64 0 : }
65 :
66 0 : void MGSelector::cleanup()
67 : {
68 : // delete all levels
69 0 : for(size_t i = 0; i < m_levels.size(); ++i)
70 0 : delete m_levels[i];
71 :
72 : m_levels.clear();
73 :
74 : // detach shared entry-attachments of section containers
75 0 : if(m_pMultiGrid){
76 0 : disable_element_support(m_supportedElements);
77 : // unregister the previously registered callback
78 0 : m_callbackId = MessageHub::SPCallbackId(NULL);
79 :
80 0 : m_pMultiGrid = NULL;
81 : }
82 :
83 0 : BaseClass::set_grid(NULL);
84 0 : }
85 :
86 0 : void MGSelector::assign_grid(MultiGrid& grid)
87 : {
88 0 : assign_grid(&grid);
89 0 : }
90 :
91 0 : void MGSelector::assign_grid(MultiGrid* grid)
92 : {
93 0 : if(grid != m_pMultiGrid){
94 0 : uint elementSupport = m_supportedElements;
95 : // if a grid already exists, we'll perform cleanup
96 0 : if(m_pMultiGrid)
97 0 : cleanup();
98 :
99 0 : m_supportedElements = SE_NONE;
100 0 : m_pMultiGrid = grid;
101 0 : BaseClass::set_grid(grid);
102 :
103 : // attach shared entry-attachments to section containers
104 0 : if(m_pMultiGrid){
105 0 : enable_element_support(elementSupport);
106 : // register the callback
107 0 : m_callbackId = m_pMultiGrid->message_hub()->register_class_callback(
108 0 : this, &ug::MGSelector::multigrid_changed);
109 0 : level_required(m_pMultiGrid->num_levels());
110 : }
111 0 : m_supportedElements = elementSupport;
112 : }
113 0 : }
114 :
115 : void MGSelector::set_supported_elements(uint shElements)
116 : {
117 : // do this in two steps:
118 : // 1: disable the element-support that is no longer required.
119 : // 2: enable the element-support that was not already enabled.
120 : // disable the elements that shall be disabled.
121 :
122 : // (the ones which shall not be set, but are currently active.)
123 : disable_element_support((~shElements) & m_supportedElements);
124 :
125 : // enable the elements that are not already enabled
126 : enable_element_support(shElements & (~m_supportedElements));
127 : }
128 :
129 0 : void MGSelector::enable_element_support(uint shElements)
130 : {
131 0 : if((shElements & SE_VERTEX) && (!elements_are_supported(SE_VERTEX)))
132 0 : m_pMultiGrid->attach_to_vertices(m_aSharedEntryVRT);
133 :
134 0 : if((shElements & SE_EDGE) && (!elements_are_supported(SE_EDGE)))
135 0 : m_pMultiGrid->attach_to_edges(m_aSharedEntryEDGE);
136 :
137 0 : if((shElements & SE_FACE) && (!elements_are_supported(SE_FACE)))
138 0 : m_pMultiGrid->attach_to_faces(m_aSharedEntryFACE);
139 :
140 0 : if((shElements & SE_VOLUME) && (!elements_are_supported(SE_VOLUME)))
141 0 : m_pMultiGrid->attach_to_volumes(m_aSharedEntryVOL);
142 :
143 0 : for(size_t i = 0; i < m_levels.size(); ++i){
144 0 : Level& lvl = *m_levels[i];
145 0 : if((shElements & SE_VERTEX) && (!elements_are_supported(SE_VERTEX)))
146 0 : lvl.m_vertices.get_container().set_pipe(
147 0 : &m_pGrid->get_attachment_pipe<Vertex>(), m_aSharedEntryVRT);
148 :
149 0 : if((shElements & SE_EDGE) && (!elements_are_supported(SE_EDGE)))
150 0 : lvl.m_edges.get_container().set_pipe(
151 0 : &m_pGrid->get_attachment_pipe<Edge>(), m_aSharedEntryEDGE);
152 :
153 0 : if((shElements & SE_FACE) && (!elements_are_supported(SE_FACE)))
154 0 : lvl.m_faces.get_container().set_pipe(
155 0 : &m_pGrid->get_attachment_pipe<Face>(), m_aSharedEntryFACE);
156 :
157 0 : if((shElements & SE_VOLUME) && (!elements_are_supported(SE_VOLUME)))
158 0 : lvl.m_volumes.get_container().set_pipe(
159 0 : &m_pGrid->get_attachment_pipe<Volume>(), m_aSharedEntryVOL);
160 : }
161 0 : ISelector::enable_element_support(shElements);
162 0 : }
163 :
164 0 : void MGSelector::disable_element_support(uint shElements)
165 : {
166 : // release the attachments in the current grid
167 0 : for(size_t i = 0; i < m_levels.size(); ++i){
168 0 : Level& lvl = *m_levels[i];
169 0 : if((shElements & SE_VERTEX) && elements_are_supported(SE_VERTEX))
170 0 : lvl.m_vertices.get_container().set_pipe(NULL);
171 :
172 0 : if((shElements & SE_EDGE) && elements_are_supported(SE_EDGE))
173 0 : lvl.m_edges.get_container().set_pipe(NULL);
174 :
175 0 : if((shElements & SE_FACE) && elements_are_supported(SE_FACE))
176 0 : lvl.m_faces.get_container().set_pipe(NULL);
177 :
178 0 : if((shElements & SE_VOLUME) && elements_are_supported(SE_VOLUME))
179 0 : lvl.m_volumes.get_container().set_pipe(NULL);
180 : }
181 :
182 0 : if((shElements & SE_VERTEX) && elements_are_supported(SE_VERTEX))
183 0 : m_pMultiGrid->detach_from_vertices(m_aSharedEntryVRT);
184 :
185 0 : if((shElements & SE_EDGE) && elements_are_supported(SE_EDGE))
186 0 : m_pMultiGrid->detach_from_edges(m_aSharedEntryEDGE);
187 :
188 0 : if((shElements & SE_FACE) && elements_are_supported(SE_FACE))
189 0 : m_pMultiGrid->detach_from_faces(m_aSharedEntryFACE);
190 :
191 0 : if((shElements & SE_VOLUME) && elements_are_supported(SE_VOLUME))
192 0 : m_pMultiGrid->detach_from_volumes(m_aSharedEntryVOL);
193 :
194 0 : ISelector::disable_element_support(shElements);
195 0 : }
196 :
197 0 : void MGSelector::add_level()
198 : {
199 : // adds a level and and initializes associated section containers.
200 0 : Level* pLvl = new Level;
201 0 : if(elements_are_supported(SE_VERTEX))
202 0 : pLvl->m_vertices.get_container().set_pipe(
203 0 : &m_pGrid->get_attachment_pipe<Vertex>(), m_aSharedEntryVRT);
204 0 : if(elements_are_supported(SE_EDGE))
205 0 : pLvl->m_edges.get_container().set_pipe(
206 0 : &m_pGrid->get_attachment_pipe<Edge>(), m_aSharedEntryEDGE);
207 0 : if(elements_are_supported(SE_FACE))
208 0 : pLvl->m_faces.get_container().set_pipe(
209 0 : &m_pGrid->get_attachment_pipe<Face>(), m_aSharedEntryFACE);
210 0 : if(elements_are_supported(SE_VOLUME))
211 0 : pLvl->m_volumes.get_container().set_pipe(
212 0 : &m_pGrid->get_attachment_pipe<Volume>(), m_aSharedEntryVOL);
213 :
214 0 : m_levels.push_back(pLvl);
215 0 : }
216 :
217 0 : void MGSelector::clear_lists()
218 : {
219 0 : for(size_t i = 0; i < m_levels.size(); ++i)
220 0 : delete m_levels[i];
221 : m_levels.clear();
222 0 : }
223 :
224 0 : void MGSelector::clear()
225 : {
226 0 : clear<Vertex>();
227 0 : clear<Edge>();
228 0 : clear<Face>();
229 0 : clear<Volume>();
230 0 : }
231 :
232 0 : void MGSelector::clear(int level)
233 : {
234 0 : clear<Vertex>(level);
235 0 : clear<Edge>(level);
236 0 : clear<Face>(level);
237 0 : clear<Volume>(level);
238 0 : }
239 :
240 0 : void MGSelector::add_to_list(Vertex* elem)
241 : {
242 0 : const int level = m_pMultiGrid->get_level(elem);
243 0 : section_container<Vertex>(level).insert(elem,
244 0 : elem->container_section());
245 0 : }
246 :
247 0 : void MGSelector::add_to_list(Edge* elem)
248 : {
249 0 : const int level = m_pMultiGrid->get_level(elem);
250 0 : section_container<Edge>(level).insert(elem,
251 0 : elem->container_section());
252 0 : }
253 :
254 0 : void MGSelector::add_to_list(Face* elem)
255 : {
256 0 : const int level = m_pMultiGrid->get_level(elem);
257 0 : section_container<Face>(level).insert(elem,
258 0 : elem->container_section());
259 0 : }
260 :
261 0 : void MGSelector::add_to_list(Volume* elem)
262 : {
263 0 : const int level = m_pMultiGrid->get_level(elem);
264 0 : section_container<Volume>(level).insert(elem,
265 0 : elem->container_section());
266 0 : }
267 :
268 0 : void MGSelector::erase_from_list(Vertex* elem)
269 : {
270 0 : const int level = m_pMultiGrid->get_level(elem);
271 0 : section_container<Vertex>(level).erase(get_level_iterator(elem),
272 0 : elem->container_section());
273 0 : }
274 0 : void MGSelector::erase_from_list(Edge* elem)
275 : {
276 0 : const int level = m_pMultiGrid->get_level(elem);
277 0 : section_container<Edge>(level).erase(get_level_iterator(elem),
278 0 : elem->container_section());
279 0 : }
280 0 : void MGSelector::erase_from_list(Face* elem)
281 : {
282 0 : const int level = m_pMultiGrid->get_level(elem);
283 0 : section_container<Face>(level).erase(get_level_iterator(elem),
284 : elem->container_section());
285 0 : }
286 :
287 0 : void MGSelector::erase_from_list(Volume* elem)
288 : {
289 0 : const int level = m_pMultiGrid->get_level(elem);
290 0 : section_container<Volume>(level).erase(get_level_iterator(elem),
291 0 : elem->container_section());
292 0 : }
293 :
294 : // geometric-object-collection
295 0 : GridObjectCollection MGSelector::get_grid_objects() const
296 : {
297 0 : uint numLevels = num_levels();
298 0 : GridObjectCollection goc(numLevels);
299 :
300 0 : for(uint i = 0; i < numLevels; ++i)
301 : {
302 0 : goc.add_level( &m_levels[i]->m_vertices,
303 : &m_levels[i]->m_edges,
304 : &m_levels[i]->m_faces,
305 0 : &m_levels[i]->m_volumes);
306 : }
307 :
308 0 : return goc;
309 : }
310 :
311 : /*
312 : void MGSelector::registered_at_grid(Grid* grid)
313 : {
314 : m_pMultiGrid = dynamic_cast<MultiGrid*>(grid);
315 : assert(m_pMultiGrid && "bad grid type!");
316 : ISelector::registered_at_grid(grid);
317 : }
318 :
319 : void MGSelector::unregistered_from_grid(Grid* grid)
320 : {
321 : ISelector::unregistered_from_grid(grid);
322 : clear_lists();
323 : }
324 : */
325 0 : void MGSelector::grid_to_be_destroyed(Grid* grid)
326 : {
327 0 : ISelector::grid_to_be_destroyed(grid);
328 0 : m_pMultiGrid = NULL;
329 0 : clear_lists();
330 0 : }
331 :
332 0 : void MGSelector::
333 : multigrid_changed(const GridMessage_MultiGridChanged& gm)
334 : {
335 0 : if(gm.message_type() == GMMGCT_LEVEL_ADDED)
336 : level_required(gm.num_levels_in_grid() - 1);
337 0 : }
338 :
339 : }// end of namespace
|