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 "subset_handler_grid.h"
35 :
36 : using namespace std;
37 :
38 : namespace ug
39 : {
40 : ////////////////////////////////////////////////////////////////////////
41 : // GridSubsetHandler implementation
42 0 : GridSubsetHandler::
43 0 : GridSubsetHandler(uint supportedElements) :
44 : ISubsetHandler(supportedElements),
45 : m_aSharedEntryVRT("SubsetHandler_SharedListEntryVRT", false),
46 : m_aSharedEntryEDGE("SubsetHandler_SharedListEntryEDGE", false),
47 : m_aSharedEntryFACE("SubsetHandler_SharedListEntryFACE", false),
48 0 : m_aSharedEntryVOL("SubsetHandler_SharedListEntryVOL", false)
49 : {
50 0 : }
51 :
52 0 : GridSubsetHandler::
53 0 : GridSubsetHandler(Grid& grid, uint supportedElements) :
54 : ISubsetHandler(supportedElements),
55 : m_aSharedEntryVRT("SubsetHandler_SharedListEntryVRT", false),
56 : m_aSharedEntryEDGE("SubsetHandler_SharedListEntryEDGE", false),
57 : m_aSharedEntryFACE("SubsetHandler_SharedListEntryFACE", false),
58 0 : m_aSharedEntryVOL("SubsetHandler_SharedListEntryVOL", false)
59 : {
60 0 : assign_grid(grid);
61 0 : }
62 :
63 0 : GridSubsetHandler::GridSubsetHandler(const GridSubsetHandler& sh) :
64 0 : ISubsetHandler(sh.m_supportedElements),
65 : m_aSharedEntryVRT("SubsetHandler_SharedListEntryVRT", false),
66 : m_aSharedEntryEDGE("SubsetHandler_SharedListEntryEDGE", false),
67 : m_aSharedEntryFACE("SubsetHandler_SharedListEntryFACE", false),
68 0 : m_aSharedEntryVOL("SubsetHandler_SharedListEntryVOL", false)
69 : {
70 0 : Grid* pGrid = sh.grid();
71 :
72 0 : if(pGrid){
73 : //TODO: remove virtual function calls from constructor
74 0 : assign_grid(*pGrid);
75 0 : assign_subset_handler(sh);
76 : }
77 0 : }
78 :
79 0 : GridSubsetHandler::~GridSubsetHandler()
80 : {
81 0 : if(m_pGrid != NULL){
82 0 : erase_subset_lists_impl();
83 0 : detach_data();
84 : }
85 0 : }
86 :
87 0 : void GridSubsetHandler::grid_to_be_destroyed(Grid* grid)
88 : {
89 : assert((m_pGrid == grid) && "ERROR in GridSubsetHandler::grid_to_be_destroyed(...): Grids do not match.");
90 0 : cleanup();
91 0 : ISubsetHandler::grid_to_be_destroyed(grid);
92 0 : }
93 :
94 0 : void GridSubsetHandler::cleanup()
95 : {
96 0 : erase_subset_lists_impl();
97 0 : detach_data();
98 : //ISubsetHandler::set_grid(NULL);
99 0 : }
100 :
101 0 : void GridSubsetHandler::assign_grid(Grid* grid)
102 : {
103 0 : if(m_pGrid == grid)
104 : return;
105 :
106 0 : if(m_pGrid)
107 0 : cleanup();
108 :
109 0 : ISubsetHandler::set_grid(grid);
110 :
111 : // attach shared entries
112 0 : if(m_pGrid){
113 0 : if(elements_are_supported(SHE_VERTEX))
114 0 : m_pGrid->attach_to_vertices(m_aSharedEntryVRT);
115 0 : if(elements_are_supported(SHE_EDGE))
116 0 : m_pGrid->attach_to_edges(m_aSharedEntryEDGE);
117 0 : if(elements_are_supported(SHE_FACE))
118 0 : m_pGrid->attach_to_faces(m_aSharedEntryFACE);
119 0 : if(elements_are_supported(SHE_VOLUME))
120 0 : m_pGrid->attach_to_volumes(m_aSharedEntryVOL);
121 : }
122 : }
123 :
124 0 : void GridSubsetHandler::assign_grid(Grid& grid)
125 : {
126 0 : assign_grid(&grid);
127 0 : }
128 :
129 0 : void GridSubsetHandler::detach_data()
130 : {
131 0 : if(elements_are_supported(SHE_VERTEX))
132 0 : m_pGrid->detach_from_vertices(m_aSharedEntryVRT);
133 0 : if(elements_are_supported(SHE_EDGE))
134 0 : m_pGrid->detach_from_edges(m_aSharedEntryEDGE);
135 0 : if(elements_are_supported(SHE_FACE))
136 0 : m_pGrid->detach_from_faces(m_aSharedEntryFACE);
137 0 : if(elements_are_supported(SHE_VOLUME))
138 0 : m_pGrid->detach_from_volumes(m_aSharedEntryVOL);
139 0 : }
140 :
141 0 : GridSubsetHandler& GridSubsetHandler::operator = (const GridSubsetHandler& sh)
142 : {
143 0 : ISubsetHandler::operator =(sh);
144 0 : return *this;
145 : }
146 :
147 0 : GridSubsetHandler& GridSubsetHandler::operator = (const ISubsetHandler& sh)
148 : {
149 0 : ISubsetHandler::operator =(sh);
150 0 : return *this;
151 : }
152 :
153 0 : void GridSubsetHandler::erase_subset_lists()
154 : {
155 0 : erase_subset_lists_impl();
156 0 : }
157 :
158 0 : void GridSubsetHandler::erase_subset_lists_impl()
159 : {
160 0 : for(uint i = 0; i < m_subsets.size(); ++i)
161 0 : delete m_subsets[i];
162 :
163 : m_subsets.clear();
164 0 : }
165 :
166 0 : void GridSubsetHandler::clear_subset_lists(int index)
167 : {
168 0 : if(m_pGrid)
169 : {
170 0 : section_container<Vertex>(index).clear();
171 0 : section_container<Edge>(index).clear();
172 0 : section_container<Face>(index).clear();
173 0 : section_container<Volume>(index).clear();
174 : }
175 0 : }
176 :
177 : template<class TElem>
178 : void
179 0 : GridSubsetHandler::
180 : assign_subset_impl(TElem* elem, int subsetIndex)
181 : {
182 : assert((m_pGrid != NULL) && "ERROR in SubsetHandler::assign_subset(): No grid assigned to SubsetHandler.");
183 :
184 : // check if we have to remove elem from a subset.
185 0 : int oldIndex = get_subset_index(elem);
186 :
187 0 : if(oldIndex != -1)
188 0 : section_container<TElem>(oldIndex).erase(get_list_iterator(elem), elem->container_section());
189 :
190 : // add the element to the subset.
191 0 : if(subsetIndex != -1)
192 : {
193 : subset_required(subsetIndex);
194 0 : section_container<TElem>(subsetIndex).insert(elem, elem->container_section());
195 : subset_assigned(elem, subsetIndex);
196 : }
197 : else{
198 : //TODO: iterator is useless!
199 : subset_assigned(elem, -1);
200 : }
201 :
202 0 : }
203 :
204 0 : void GridSubsetHandler::assign_subset(Vertex* elem, int subsetIndex)
205 : {
206 0 : if(elements_are_supported(SHE_VERTEX))
207 0 : assign_subset_impl(elem, subsetIndex);
208 0 : }
209 :
210 0 : void GridSubsetHandler::assign_subset(Edge* elem, int subsetIndex)
211 : {
212 0 : if(elements_are_supported(SHE_EDGE))
213 0 : assign_subset_impl(elem, subsetIndex);
214 0 : }
215 :
216 0 : void GridSubsetHandler::assign_subset(Face* elem, int subsetIndex)
217 : {
218 0 : if(elements_are_supported(SHE_FACE))
219 0 : assign_subset_impl(elem, subsetIndex);
220 0 : }
221 :
222 0 : void GridSubsetHandler::assign_subset(Volume* elem, int subsetIndex)
223 : {
224 0 : if(elements_are_supported(SHE_VOLUME))
225 0 : assign_subset_impl(elem, subsetIndex);
226 0 : }
227 :
228 0 : void GridSubsetHandler::
229 : change_subset_indices(int indOld, int indNew)
230 : {
231 0 : if(m_pGrid)
232 : {
233 0 : if(elements_are_supported(SHE_VERTEX))
234 0 : change_elem_subset_indices<Vertex>(indOld, indNew);
235 0 : if(elements_are_supported(SHE_EDGE))
236 0 : change_elem_subset_indices<Edge>(indOld, indNew);
237 0 : if(elements_are_supported(SHE_FACE))
238 0 : change_elem_subset_indices<Face>(indOld, indNew);
239 0 : if(elements_are_supported(SHE_VOLUME)){
240 0 : change_elem_subset_indices<Volume>(indOld, indNew);
241 : }
242 : }
243 0 : }
244 :
245 0 : void GridSubsetHandler::add_required_subset_lists(int maxIndex)
246 : {
247 0 : while((int)m_subsets.size() <= maxIndex){
248 : // initialize section containers
249 0 : Subset* sub = new Subset;
250 0 : if(elements_are_supported(SHE_VERTEX))
251 0 : sub->m_vertices.get_container().set_pipe(
252 0 : &m_pGrid->get_attachment_pipe<Vertex>(), m_aSharedEntryVRT);
253 0 : if(elements_are_supported(SHE_EDGE))
254 0 : sub->m_edges.get_container().set_pipe(
255 0 : &m_pGrid->get_attachment_pipe<Edge>(), m_aSharedEntryEDGE);
256 0 : if(elements_are_supported(SHE_FACE))
257 0 : sub->m_faces.get_container().set_pipe(
258 0 : &m_pGrid->get_attachment_pipe<Face>(), m_aSharedEntryFACE);
259 0 : if(elements_are_supported(SHE_VOLUME))
260 0 : sub->m_volumes.get_container().set_pipe(
261 0 : &m_pGrid->get_attachment_pipe<Volume>(), m_aSharedEntryVOL);
262 0 : m_subsets.push_back(sub);
263 : }
264 0 : }
265 :
266 0 : void GridSubsetHandler::erase_subset_lists(int index)
267 : {
268 0 : delete m_subsets[index];
269 0 : for(uint i = index + 1; i < num_subsets_in_list(); ++i)
270 0 : m_subsets[i-1] = m_subsets[i];
271 0 : m_subsets.resize(m_subsets.size() - 1);
272 0 : }
273 :
274 0 : void GridSubsetHandler::swap_subset_lists(int ind1, int ind2)
275 : {
276 0 : Subset* pTmp = m_subsets[ind1];
277 0 : m_subsets[ind1] = m_subsets[ind2];
278 0 : m_subsets[ind2] = pTmp;
279 0 : }
280 :
281 0 : void GridSubsetHandler::move_subset_lists(int indexFrom, int indexTo)
282 : {
283 : int moveDir = 0;
284 : // we have to distinguish two cases
285 0 : if(indexFrom < indexTo)
286 : moveDir = 1;
287 0 : else if(indexTo < indexFrom)
288 : moveDir = -1;
289 :
290 : if(moveDir != 0)
291 : {
292 : // store pointer to the from-subset
293 0 : Subset* pFrom = m_subsets[indexFrom];
294 :
295 0 : for(int i = indexFrom; i != indexTo; i+= moveDir)
296 : {
297 0 : int iNext = i+moveDir;
298 :
299 : // move pointer
300 0 : m_subsets[i] = m_subsets[iNext];
301 : }
302 :
303 : // assign stored pointer
304 0 : m_subsets[indexTo] = pFrom;
305 : }
306 0 : }
307 :
308 : /// join the subset-lists but do not touch the subset-indices.
309 0 : void GridSubsetHandler::join_subset_lists(int target, int src1, int src2)
310 : {
311 0 : Subset& t = *m_subsets[target];
312 0 : Subset& s1 = *m_subsets[src1];
313 0 : Subset& s2 = *m_subsets[src2];
314 :
315 0 : if(target != src1){
316 0 : t.m_vertices.transfer_elements(s1.m_vertices);
317 0 : t.m_edges.transfer_elements(s1.m_edges);
318 0 : t.m_faces.transfer_elements(s1.m_faces);
319 0 : t.m_volumes.transfer_elements(s1.m_volumes);
320 : }
321 0 : if(target != src2){
322 0 : t.m_vertices.transfer_elements(s2.m_vertices);
323 0 : t.m_edges.transfer_elements(s2.m_edges);
324 0 : t.m_faces.transfer_elements(s2.m_faces);
325 0 : t.m_volumes.transfer_elements(s2.m_volumes);
326 : }
327 0 : }
328 :
329 : /*
330 : void GridSubsetHandler::
331 : register_subset_elements_at_pipe()
332 : {
333 : for(size_t i = 0; i < num_subsets_in_list(); ++i)
334 : {
335 : // register vertices
336 : for(VertexIterator iter = begin<Vertex>(i);
337 : iter != end<Vertex>(i); ++iter)
338 : register_at_pipe(*iter);
339 :
340 : // register edges
341 : for(EdgeIterator iter = begin<Edge>(i);
342 : iter != end<Edge>(i); ++iter)
343 : register_at_pipe(*iter);
344 :
345 : // register faces
346 : for(FaceIterator iter = begin<Face>(i);
347 : iter != end<Face>(i); ++iter)
348 : register_at_pipe(*iter);
349 :
350 : // register volumes
351 : for(VolumeIterator iter = begin<Volume>(i);
352 : iter != end<Volume>(i); ++iter)
353 : register_at_pipe(*iter);
354 : }
355 : }*/
356 :
357 :
358 : GridObjectCollection
359 0 : GridSubsetHandler::
360 : get_grid_objects_in_subset(int subsetIndex) const
361 : {
362 : //todo: replace with throw
363 : assert((subsetIndex >= 0) && (subsetIndex < (int)num_subsets_in_list()) && "invalid subset index!");
364 :
365 0 : subset_required(subsetIndex);
366 : return GridObjectCollection(&m_subsets[subsetIndex]->m_vertices,
367 : &m_subsets[subsetIndex]->m_edges,
368 : &m_subsets[subsetIndex]->m_faces,
369 0 : &m_subsets[subsetIndex]->m_volumes);
370 : }
371 :
372 : GridObjectCollection
373 0 : GridSubsetHandler::
374 : get_grid_objects() const
375 : {
376 : uint numSubsets = num_subsets_in_list();
377 0 : GridObjectCollection goc(numSubsets);
378 0 : for(uint i = 0; i < numSubsets; ++i)
379 : {
380 0 : goc.add_level( &m_subsets[i]->m_vertices,
381 : &m_subsets[i]->m_edges,
382 : &m_subsets[i]->m_faces,
383 0 : &m_subsets[i]->m_volumes);
384 : }
385 :
386 0 : return goc;
387 : }
388 : /*
389 : size_t GridSubsetHandler::
390 : collect_subset_elements(std::vector<Vertex*>& vrtsOut, int subsetIndex) const
391 : {
392 : return collect_subset_elements_impl(vrtsOut, subsetIndex);
393 : }
394 :
395 : size_t GridSubsetHandler::
396 : collect_subset_elements(std::vector<Edge*>& edgesOut, int subsetIndex) const
397 : {
398 : return collect_subset_elements_impl(edgesOut, subsetIndex);
399 : }
400 :
401 : size_t GridSubsetHandler::
402 : collect_subset_elements(std::vector<Face*>& facesOut, int subsetIndex) const
403 : {
404 : return collect_subset_elements_impl(facesOut, subsetIndex);
405 : }
406 :
407 : size_t GridSubsetHandler::
408 : collect_subset_elements(std::vector<Volume*>& volsOut, int subsetIndex) const
409 : {
410 : return collect_subset_elements_impl(volsOut, subsetIndex);
411 : }
412 :
413 : template <class TElem>
414 : size_t GridSubsetHandler::
415 : collect_subset_elements_impl(std::vector<TElem*>& elemsOut, int subsetIndex) const
416 : {
417 : typedef typename geometry_traits<TElem>::iterator ElemIter;
418 : typedef typename geometry_traits<TElem>::const_iterator ConstElemIter;
419 :
420 : elemsOut.clear();
421 :
422 : if(!m_pGrid){
423 : return 0;
424 : }
425 :
426 : if(subsetIndex < 0){
427 : // iterate over all elements of the underlying grid and compare indices
428 : Grid& grid = *m_pGrid;
429 :
430 : for(ElemIter iter = grid.begin<TElem>(); iter != grid.end<TElem>(); ++iter)
431 : {
432 : if(get_subset_index(*iter) == -1)
433 : elemsOut.push_back(*iter);
434 : }
435 : }
436 : else{
437 : elemsOut.reserve(num<TElem>(subsetIndex));
438 : for(ConstElemIter iter = begin<TElem>(subsetIndex);
439 : iter != end<TElem>(subsetIndex); ++iter)
440 : {
441 : elemsOut.push_back(*iter);
442 : }
443 : }
444 :
445 : return elemsOut.size();
446 : }
447 : */
448 : }// end of namespace
|