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_interface.h"
35 :
36 : using namespace std;
37 :
38 : namespace ug
39 : {
40 : ////////////////////////////////////////////////////////////////////////
41 : // SubsetInfo implementation
42 0 : SubsetInfo::SubsetInfo()
43 : {
44 0 : name = "";
45 0 : materialIndex = -1;
46 0 : subsetState = SS_NONE;
47 0 : }
48 :
49 0 : void SubsetInfo::
50 : set_property(const char* name, Variant prop)
51 : {
52 0 : m_propertyMap[name] = prop;
53 0 : }
54 :
55 0 : void SubsetInfo::
56 : set_property(const std::string& name, Variant prop)
57 : {
58 0 : m_propertyMap[name] = prop;
59 0 : }
60 :
61 0 : Variant SubsetInfo::
62 : get_property(const char* name, Variant defaultValue) const
63 : {
64 0 : PropertyMap::const_iterator iter = m_propertyMap.find(name);
65 0 : if(iter == m_propertyMap.end())
66 0 : return defaultValue;
67 0 : return iter->second;
68 : }
69 :
70 0 : Variant SubsetInfo::
71 : get_property(const std::string& name, Variant defaultValue) const
72 : {
73 : PropertyMap::const_iterator iter = m_propertyMap.find(name);
74 0 : if(iter == m_propertyMap.end())
75 0 : return defaultValue;
76 0 : return iter->second;
77 : }
78 :
79 :
80 : ////////////////////////////////////////////////////////////////////////
81 : // ISubsetHandler implementation
82 0 : ISubsetHandler::
83 0 : ISubsetHandler(uint supportedElements) :
84 0 : m_aSubsetIndex("ISubsetHandler_SubsetIndex", false)
85 : // m_aDataIndex("ISubsetHandler_DataIndex", false)
86 : {
87 0 : m_pGrid = NULL;
88 0 : m_supportedElements = supportedElements;
89 0 : m_defaultSubsetIndex = -1;
90 0 : m_bSubsetInheritanceEnabled = true;
91 0 : m_bStrictInheritanceEnabled = false;
92 : // m_bSubsetAttachmentsEnabled = false;
93 0 : m_defaultSubsetInfo.name = "defSub";
94 0 : m_defaultSubsetInfo.materialIndex = 0;
95 : m_defaultSubsetInfo.color = vector4(1., 1., 1., 1.);
96 0 : m_defaultSubsetInfo.subsetState = SS_NONE;
97 0 : }
98 :
99 0 : ISubsetHandler::
100 0 : ISubsetHandler(Grid& grid, uint supportedElements) :
101 0 : m_aSubsetIndex("ISubsetHandler_SubsetIndex", false)
102 : //m_aDataIndex("ISubsetHandler_DataIndex", false)
103 : {
104 0 : m_pGrid = &grid;
105 0 : m_supportedElements = SHE_NONE;
106 0 : m_defaultSubsetIndex = -1;
107 0 : m_bSubsetInheritanceEnabled = true;
108 0 : m_bStrictInheritanceEnabled = false;
109 : //m_bSubsetAttachmentsEnabled = false;
110 0 : m_defaultSubsetInfo.name = "defSub";
111 0 : m_defaultSubsetInfo.materialIndex = 0;
112 : m_defaultSubsetInfo.color = vector4(1., 1., 1., 1.);
113 0 : m_defaultSubsetInfo.subsetState = SS_NONE;
114 :
115 0 : enable_element_support(supportedElements);
116 0 : grid.register_observer(this, OT_GRID_OBSERVER | OT_VERTEX_OBSERVER | OT_EDGE_OBSERVER |
117 : OT_FACE_OBSERVER | OT_VOLUME_OBSERVER);
118 0 : }
119 :
120 0 : ISubsetHandler::
121 0 : ~ISubsetHandler()
122 : {
123 0 : if(m_pGrid)
124 : {
125 : // clear the subsets
126 : m_subsetInfos.clear();
127 :
128 : // disable all currently supported elements (this will remove any attachments)
129 0 : disable_element_support(m_supportedElements);
130 :
131 : // clear attachment data
132 : /*if(subset_attachments_are_enabled())
133 : {
134 : m_pGrid->detach_from_vertices(m_aDataIndex);
135 : m_pGrid->detach_from_edges(m_aDataIndex);
136 : m_pGrid->detach_from_faces(m_aDataIndex);
137 : m_pGrid->detach_from_volumes(m_aDataIndex);
138 :
139 : // clear pipes
140 : clear_attachment_pipes();
141 : }*/
142 :
143 0 : m_pGrid->unregister_observer(this);
144 : }
145 0 : }
146 :
147 0 : ISubsetHandler& ISubsetHandler::operator = (const ISubsetHandler& sh)
148 : {
149 0 : clear();
150 0 : assign_subset_handler(sh);
151 0 : return *this;
152 : }
153 :
154 : template <class TIterator> static void
155 0 : CopySubsetIndices(ISubsetHandler& dest, const ISubsetHandler& src,
156 : TIterator destIterBegin, TIterator destIterEnd,
157 : TIterator srcIterBegin, TIterator srcIterEnd)
158 : {
159 0 : while((srcIterBegin != srcIterEnd) && (destIterBegin != destIterEnd))
160 : {
161 0 : dest.assign_subset(*destIterBegin, src.get_subset_index(*srcIterBegin));
162 : ++destIterBegin;
163 : ++srcIterBegin;
164 : }
165 0 : }
166 :
167 0 : void ISubsetHandler::assign_subset_handler(const ISubsetHandler& sh)
168 : {
169 : // get the source grid
170 0 : Grid* srcGrid = sh.grid();
171 0 : Grid* destGrid = m_pGrid;
172 :
173 : // copy status and options
174 0 : set_supported_elements(sh.m_supportedElements);
175 0 : enable_subset_inheritance(sh.m_bSubsetInheritanceEnabled);
176 0 : set_default_subset_index(sh.m_defaultSubsetIndex);
177 0 : set_default_subset_info(sh.m_defaultSubsetInfo);
178 :
179 : //TODO: enable attachment support based on the source-hanlders attachment support!?!
180 0 : subset_required(sh.num_subsets() - 1);
181 :
182 : // make sure that both accessors have a valid grid
183 0 : if(srcGrid && destGrid){
184 : //LOG("sh-copying -");
185 : // assign the subsets for each element-type
186 0 : if(elements_are_supported(SHE_VERTEX)){
187 : //LOG(" vrts -");
188 0 : CopySubsetIndices(*this, sh, destGrid->begin<Vertex>(), destGrid->end<Vertex>(),
189 0 : srcGrid->begin<Vertex>(), srcGrid->end<Vertex>());
190 : }
191 :
192 0 : if(elements_are_supported(SHE_EDGE)){
193 : //LOG(" edges -");
194 0 : CopySubsetIndices(*this, sh, destGrid->begin<Edge>(), destGrid->end<Edge>(),
195 0 : srcGrid->begin<Edge>(), srcGrid->end<Edge>());
196 : }
197 :
198 0 : if(elements_are_supported(SHE_FACE)){
199 : //LOG(" faces -");
200 0 : CopySubsetIndices(*this, sh, destGrid->begin<Face>(), destGrid->end<Face>(),
201 0 : srcGrid->begin<Face>(), srcGrid->end<Face>());
202 : }
203 :
204 0 : if(elements_are_supported(SHE_VOLUME)){
205 : //LOG(" volumes -");
206 0 : CopySubsetIndices(*this, sh, destGrid->begin<Volume>(), destGrid->end<Volume>(),
207 0 : srcGrid->begin<Volume>(), srcGrid->end<Volume>());
208 : }
209 :
210 : //LOG(endl);
211 : //TODO: copy attachments!?!
212 : }
213 :
214 : // copy subset infos
215 0 : for(int i = 0; i < num_subsets(); ++i)
216 0 : set_subset_info(i, sh.subset_info(i));
217 0 : }
218 :
219 :
220 0 : void ISubsetHandler::
221 : assign_subset(GridObject* elem, int subsetIndex)
222 : {
223 0 : switch(elem->base_object_id()){
224 0 : case VERTEX: assign_subset(static_cast<Vertex*>(elem), subsetIndex); break;
225 0 : case EDGE: assign_subset(static_cast<Edge*>(elem), subsetIndex); break;
226 0 : case FACE: assign_subset(static_cast<Face*>(elem), subsetIndex); break;
227 0 : case VOLUME: assign_subset(static_cast<Volume*>(elem), subsetIndex); break;
228 0 : default:
229 0 : UG_THROW("Unsupported base-object-id encountered: " << elem->base_object_id());
230 : }
231 0 : }
232 :
233 :
234 0 : void ISubsetHandler::
235 : create_required_subsets(int index)
236 : {
237 0 : m_subsetInfos.resize(index+1, m_defaultSubsetInfo);
238 :
239 : /*if(subset_attachments_are_enabled())
240 : resize_attachment_pipes(index+1);*/
241 :
242 0 : add_required_subset_lists(index);
243 0 : }
244 :
245 : void
246 0 : ISubsetHandler::
247 : set_grid(Grid* grid)
248 : {
249 0 : if(m_pGrid != NULL){
250 0 : clear();
251 :
252 : // disable all currently supported elements (this will remove any attachments)
253 0 : disable_element_support(m_supportedElements);
254 :
255 : // clear attachment data
256 : /*if(subset_attachments_are_enabled())
257 : {
258 : m_pGrid->detach_from_vertices(m_aDataIndex);
259 : m_pGrid->detach_from_edges(m_aDataIndex);
260 : m_pGrid->detach_from_faces(m_aDataIndex);
261 : m_pGrid->detach_from_volumes(m_aDataIndex);
262 :
263 : // clear pipes
264 : clear_attachment_pipes();
265 : }*/
266 :
267 0 : m_pGrid->unregister_observer(this);
268 0 : m_pGrid = NULL;
269 : }
270 :
271 0 : if(grid){
272 0 : m_pGrid = grid;
273 :
274 : // initialise attachments and accessors.
275 : // do this whith a little trick:
276 : // set the supported-element-options to SHE_NONE,
277 : // then call enable for all element-types that should be supported.
278 0 : uint tmpOpts = m_supportedElements;
279 0 : m_supportedElements = SHE_NONE;
280 0 : enable_element_support(tmpOpts);
281 :
282 : // enable attachments - if required
283 : /*if(subset_attachments_are_enabled())
284 : {
285 : m_bSubsetAttachmentsEnabled = false;
286 : enable_subset_attachments(true);
287 : }*/
288 :
289 0 : m_pGrid->register_observer(this, OT_GRID_OBSERVER | OT_VERTEX_OBSERVER | OT_EDGE_OBSERVER |
290 : OT_FACE_OBSERVER | OT_VOLUME_OBSERVER);
291 : }
292 0 : }
293 :
294 0 : void ISubsetHandler::
295 : set_default_subset_index(int subsetIndex)
296 : {
297 0 : m_defaultSubsetIndex = subsetIndex;
298 0 : if(subsetIndex < 0)
299 0 : m_defaultSubsetIndex = -1;
300 0 : }
301 :
302 :
303 0 : Grid* ISubsetHandler::
304 : grid() const
305 : {
306 0 : return m_pGrid;
307 : }
308 :
309 0 : bool ISubsetHandler::
310 : elements_are_supported(uint shElements) const
311 : {
312 0 : return (m_supportedElements & shElements) == shElements;
313 : }
314 :
315 0 : void ISubsetHandler::
316 : set_supported_elements(uint shElements)
317 : {
318 : // do this in two steps:
319 : // 1: disable the element-support that is no longer required.
320 : // 2: enable the element-support that was not already enabled.
321 : // disable the elements that shall be disabled.
322 :
323 : // (the ones which shall not be set, but are currently active.)
324 0 : disable_element_support((~shElements) & m_supportedElements);
325 :
326 : // enable the elements that are not already enabled
327 0 : enable_element_support(shElements & (~m_supportedElements));
328 0 : }
329 :
330 0 : void ISubsetHandler::
331 : enable_element_support(uint shElements)
332 : {
333 : // if no grid is assigned, we can't do anything.
334 0 : if(m_pGrid)
335 : {
336 : // check for each option whether it should be enabled.
337 : // to reduce unnecessary operations, we have to make sure that
338 : // that option hasn't already been enabled.
339 :
340 0 : if((shElements & SHE_VERTEX) &&
341 0 : (!elements_are_supported(SHE_VERTEX)))
342 : {
343 : //LOG("enabling vertex support\n");
344 : // enable vertex-support.
345 0 : m_pGrid->attach_to_vertices(m_aSubsetIndex);
346 0 : m_aaSubsetIndexVRT.access(*m_pGrid, m_aSubsetIndex);
347 0 : m_supportedElements |= SHE_VERTEX;
348 0 : reset_subset_indices(SHE_VERTEX);
349 : }
350 :
351 0 : if((shElements & SHE_EDGE) &&
352 0 : (!elements_are_supported(SHE_EDGE)))
353 : {
354 : //LOG("enabling edge support\n");
355 : // enable edge support
356 0 : m_pGrid->attach_to_edges(m_aSubsetIndex);
357 0 : m_aaSubsetIndexEDGE.access(*m_pGrid, m_aSubsetIndex);
358 0 : m_supportedElements |= SHE_EDGE;
359 0 : reset_subset_indices(SHE_EDGE);
360 : }
361 :
362 0 : if((shElements & SHE_FACE) &&
363 0 : (!elements_are_supported(SHE_FACE)))
364 : {
365 : //LOG("enabling face support\n");
366 : // enable face support
367 0 : m_pGrid->attach_to_faces(m_aSubsetIndex);
368 0 : m_aaSubsetIndexFACE.access(*m_pGrid, m_aSubsetIndex);
369 0 : m_supportedElements |= SHE_FACE;
370 0 : reset_subset_indices(SHE_FACE);
371 : }
372 :
373 0 : if((shElements & SHE_VOLUME) &&
374 0 : (!elements_are_supported(SHE_VOLUME)))
375 : {
376 : //LOG("enabling volume support\n");
377 : // enable volume support
378 0 : m_pGrid->attach_to_volumes(m_aSubsetIndex);
379 0 : m_aaSubsetIndexVOL.access(*m_pGrid, m_aSubsetIndex);
380 0 : m_supportedElements |= SHE_VOLUME;
381 0 : reset_subset_indices(SHE_VOLUME);
382 : }
383 : }
384 0 : }
385 :
386 0 : void ISubsetHandler::
387 : disable_element_support(uint shElements)
388 : {
389 : // if no grid is assigned, we can't do anything.
390 0 : if(m_pGrid)
391 : {
392 : // check for each option whether it should be disabled.
393 : // to reduce unnecessary operations, we have to make sure that
394 : // that option hasn't already been disabled.
395 :
396 0 : if((shElements & SHE_VERTEX) && elements_are_supported(SHE_VERTEX))
397 : {
398 : //LOG("disabling vertex support\n");
399 0 : m_pGrid->detach_from_vertices(m_aSubsetIndex);
400 : }
401 :
402 0 : if((shElements & SHE_EDGE) && elements_are_supported(SHE_EDGE))
403 : {
404 : //LOG("disabling edge support\n");
405 0 : m_pGrid->detach_from_edges(m_aSubsetIndex);
406 : }
407 :
408 0 : if((shElements & SHE_FACE) && elements_are_supported(SHE_FACE))
409 : {
410 : //LOG("disabling face support\n");
411 0 : m_pGrid->detach_from_faces(m_aSubsetIndex);
412 : }
413 :
414 0 : if((shElements & SHE_VOLUME) && elements_are_supported(SHE_VOLUME))
415 : {
416 : //LOG("disabling volume support\n");
417 0 : m_pGrid->detach_from_volumes(m_aSubsetIndex);
418 : }
419 : }
420 :
421 : // remove the disabled elements from the set of currently supported elements.
422 0 : m_supportedElements &= (~shElements);
423 0 : }
424 :
425 0 : void ISubsetHandler::
426 : enable_subset_inheritance(bool bEnable)
427 : {
428 0 : m_bSubsetInheritanceEnabled = bEnable;
429 0 : }
430 :
431 0 : void ISubsetHandler::
432 : enable_strict_inheritance(bool bEnable)
433 : {
434 0 : m_bStrictInheritanceEnabled = bEnable;
435 0 : }
436 :
437 0 : const char* ISubsetHandler::
438 : get_subset_name(int subsetIndex) const
439 : {
440 : // check that subset exists
441 0 : if(subsetIndex < 0 || subsetIndex >= num_subsets()){
442 0 : UG_THROW("Bad subset index " << subsetIndex
443 : << ". Only " << num_subsets() << " subsets are present.");
444 : }
445 :
446 : // get subset info
447 0 : const SubsetInfo& subsetInfo = subset_info(subsetIndex);
448 :
449 0 : return subsetInfo.name.c_str();
450 : }
451 :
452 0 : void ISubsetHandler::
453 : set_subset_name(const char* name, int subsetIndex)
454 : {
455 : subset_required(subsetIndex);
456 :
457 : // get subset info
458 0 : SubsetInfo& subsetInfo = subset_info(subsetIndex);
459 :
460 0 : subsetInfo.name = std::string(name);
461 0 : }
462 :
463 0 : void ISubsetHandler::
464 : set_subset_info(int subsetIndex, const SubsetInfo& subsetInfo)
465 : {
466 : subset_required(subsetIndex);
467 0 : m_subsetInfos[subsetIndex] = subsetInfo;
468 0 : }
469 :
470 0 : SubsetInfo& ISubsetHandler::
471 : subset_info(int subsetIndex)
472 : {
473 0 : if(subsetIndex < 0){
474 0 : UG_THROW("Bad subset index " << subsetIndex << ". No subset-info available for this subset.");
475 : }
476 :
477 : subset_required(subsetIndex);
478 0 : return m_subsetInfos[subsetIndex];
479 : }
480 :
481 :
482 0 : const SubsetInfo& ISubsetHandler::
483 : subset_info(int subsetIndex) const
484 : {
485 0 : if(subsetIndex < 0 || subsetIndex >= num_subsets()){
486 0 : UG_THROW("Bad subset index " << subsetIndex
487 : << ". Only " << num_subsets() << " subsets are present.");
488 : }
489 :
490 0 : return m_subsetInfos[subsetIndex];
491 : }
492 :
493 0 : void ISubsetHandler::
494 : set_default_subset_info(const SubsetInfo& defSI)
495 : {
496 0 : m_defaultSubsetInfo = defSI;
497 0 : }
498 :
499 0 : void ISubsetHandler::
500 : clear()
501 : {
502 : // erase subsets
503 0 : erase_subset_lists();
504 :
505 : // erase subset indfos
506 : m_subsetInfos.clear();
507 :
508 : // reset all element subset-indices.
509 0 : reset_subset_indices();
510 0 : }
511 :
512 0 : void ISubsetHandler::
513 : clear_subset(int subsetIndex)
514 : {
515 : assert((subsetIndex >= 0) && (subsetIndex < (int)num_subsets()) &&
516 : "ERROR in SubsetHandler::clear_subset(): bad subset index.");
517 :
518 0 : m_subsetInfos[subsetIndex] = SubsetInfo();
519 :
520 0 : change_subset_indices(subsetIndex, -1);
521 0 : clear_subset_lists(subsetIndex);
522 0 : }
523 :
524 0 : void ISubsetHandler::
525 : clear_subsets()
526 : {
527 0 : for(int i = 0; i < (int)num_subsets(); ++i)
528 0 : clear_subset(i);
529 0 : }
530 :
531 :
532 : template <class TElem, class TAAInd>
533 : static void
534 : ResetSubsetIndices(Grid* pGrid, TAAInd& aaInd)
535 : {
536 : typedef typename geometry_traits<TElem>::iterator iterator;
537 : // in the given subset to newInd.
538 : for(iterator iter = pGrid->begin<TElem>();
539 0 : iter != pGrid->end<TElem>(); iter++)
540 0 : aaInd[*iter] = -1;
541 : }
542 :
543 0 : void ISubsetHandler::
544 : reset_subset_indices(uint shElements)
545 : {
546 0 : if(m_pGrid)
547 : {
548 0 : if((shElements & SHE_VERTEX) && elements_are_supported(SHE_VERTEX))
549 0 : ResetSubsetIndices<Vertex>(m_pGrid, m_aaSubsetIndexVRT);
550 0 : if((shElements & SHE_EDGE) && elements_are_supported(SHE_EDGE))
551 0 : ResetSubsetIndices<Edge>(m_pGrid, m_aaSubsetIndexEDGE);
552 0 : if((shElements & SHE_FACE) && elements_are_supported(SHE_FACE))
553 0 : ResetSubsetIndices<Face>(m_pGrid, m_aaSubsetIndexFACE);
554 0 : if((shElements & SHE_VOLUME) && elements_are_supported(SHE_VOLUME))
555 0 : ResetSubsetIndices<Volume>(m_pGrid, m_aaSubsetIndexVOL);
556 : }
557 0 : }
558 :
559 0 : int ISubsetHandler::
560 : get_subset_index(GridObject* elem) const
561 : {
562 0 : uint type = elem->base_object_id();
563 0 : switch(type)
564 : {
565 : case VERTEX:
566 : return get_subset_index(reinterpret_cast<Vertex*>(elem));
567 : case EDGE:
568 : return get_subset_index(reinterpret_cast<Edge*>(elem));
569 : case FACE:
570 : return get_subset_index(reinterpret_cast<Face*>(elem));
571 : case VOLUME:
572 : return get_subset_index(reinterpret_cast<Volume*>(elem));
573 : }
574 :
575 : // we should never arrive at this point
576 : assert(!"ERROR in SubsetHandler::get_subset_index(GridObject* elem): Program should never reach this point!");
577 : return -1;
578 : }
579 :
580 0 : int ISubsetHandler::
581 : get_subset_index(const char* name) const
582 : {
583 0 : for(int i = 0; i < num_subsets(); ++i){
584 0 : if(subset_info(i).name.compare(name) == 0)
585 0 : return i;
586 : }
587 : return -1;
588 : }
589 :
590 0 : void ISubsetHandler::
591 : insert_subset(int subsetIndex)
592 : {
593 : // append required subsets
594 0 : if(subsetIndex >= 0)
595 : {
596 : // make sure that the subset-infos
597 : subset_required(num_subsets());
598 0 : if(subsetIndex < (int)num_subsets()-1)
599 0 : move_subset(num_subsets() - 1, subsetIndex);
600 : }
601 0 : }
602 :
603 0 : void ISubsetHandler::
604 : erase_subset(int subsetIndex)
605 : {
606 : // assign all elements of this subset to -1
607 : // delete the subset
608 : // move all subsets with higher index one entry up
609 : // and correct indices of assigned elements.
610 0 : if((subsetIndex >= 0) && (subsetIndex < (int)num_subsets()))
611 : {
612 0 : change_subset_indices(subsetIndex, -1);
613 :
614 : // clear and delete pipes of erased subset
615 : /*if(subset_attachments_are_enabled())
616 : {
617 : clear_attachment_pipes(subsetIndex);
618 : delete m_vertexAttachmentPipes[subsetIndex];
619 : delete m_edgeAttachmentPipes[subsetIndex];
620 : delete m_faceAttachmentPipes[subsetIndex];
621 : delete m_volumeAttachmentPipes[subsetIndex];
622 : }*/
623 :
624 0 : for(int i = subsetIndex + 1; i < num_subsets(); ++i)
625 : {
626 : // alter indices
627 0 : change_subset_indices(i, i-1);
628 :
629 : // move the subset
630 0 : m_subsetInfos[i-1] = m_subsetInfos[i];
631 :
632 : // move the pipes
633 : /*if(subset_attachments_are_enabled())
634 : {
635 : m_vertexAttachmentPipes[i-1] = m_vertexAttachmentPipes[i];
636 : m_edgeAttachmentPipes[i-1] = m_edgeAttachmentPipes[i];
637 : m_faceAttachmentPipes[i-1] = m_faceAttachmentPipes[i];
638 : m_volumeAttachmentPipes[i-1] = m_volumeAttachmentPipes[i];
639 : }*/
640 : }
641 :
642 : // resize the subset vector
643 0 : uint numNewSubsets = num_subsets() - 1;
644 0 : erase_subset_lists(subsetIndex);
645 0 : m_subsetInfos.resize(numNewSubsets);
646 : /*if(subset_attachments_are_enabled())
647 : resize_attachment_pipes(numNewSubsets);*/
648 : }
649 : else{
650 0 : UG_THROW("bad subset index: " << subsetIndex);
651 : }
652 0 : }
653 :
654 0 : void ISubsetHandler::
655 : swap_subsets(int subsetIndex1, int subsetIndex2)
656 : {
657 0 : if((subsetIndex1 >= 0) && (subsetIndex1 < (int)num_subsets())
658 0 : && (subsetIndex2 >= 0) && (subsetIndex2 < (int)num_subsets()))
659 : {
660 : // set all indices of subset1 to subsetIndex2 and vice versa.
661 : // swap pointers of subsets afterwards
662 0 : change_subset_indices(subsetIndex1, subsetIndex2);
663 0 : change_subset_indices(subsetIndex2, subsetIndex1);
664 :
665 : // swap pointers
666 0 : SubsetInfo tmpSI = m_subsetInfos[subsetIndex1];
667 0 : m_subsetInfos[subsetIndex1] = m_subsetInfos[subsetIndex2];
668 0 : m_subsetInfos[subsetIndex2] = tmpSI;
669 :
670 : // store from-attachment-pipes
671 : /*if(subset_attachments_are_enabled())
672 : {
673 : VertexAttachmentPipe* apFromVrt = m_vertexAttachmentPipes[subsetIndex1];
674 : m_vertexAttachmentPipes[subsetIndex1] = m_vertexAttachmentPipes[subsetIndex2];
675 : m_vertexAttachmentPipes[subsetIndex2] = apFromVrt;
676 : EdgeAttachmentPipe* apFromEdge = m_edgeAttachmentPipes[subsetIndex1];
677 : m_edgeAttachmentPipes[subsetIndex1] = m_edgeAttachmentPipes[subsetIndex2];
678 : m_edgeAttachmentPipes[subsetIndex2] = apFromEdge;
679 : FaceAttachmentPipe* apFromFace = m_faceAttachmentPipes[subsetIndex1];
680 : m_faceAttachmentPipes[subsetIndex1] = m_faceAttachmentPipes[subsetIndex2];
681 : m_faceAttachmentPipes[subsetIndex2] = apFromFace;
682 : VolumeAttachmentPipe* apFromVol = m_volumeAttachmentPipes[subsetIndex1];
683 : m_volumeAttachmentPipes[subsetIndex1] = m_volumeAttachmentPipes[subsetIndex2];
684 : m_volumeAttachmentPipes[subsetIndex2] = apFromVol;
685 : }
686 : */
687 : // swap the lists
688 0 : swap_subset_lists(subsetIndex1, subsetIndex2);
689 : }
690 : else{
691 0 : UG_THROW("bad subset indices: " << subsetIndex1 << ", " << subsetIndex2);
692 : }
693 0 : }
694 :
695 0 : void ISubsetHandler::
696 : move_subset(int indexFrom, int indexTo)
697 : {
698 0 : if((indexFrom >= 0) && (indexFrom < (int)num_subsets()) && (indexTo >= 0))
699 : {
700 : int moveDir = 0;
701 : // we have to distinguish two cases
702 0 : if(indexFrom < indexTo)
703 : moveDir = 1;
704 0 : else if(indexTo < indexFrom)
705 : moveDir = -1;
706 :
707 : if(moveDir != 0)
708 : {
709 : // check if we have to append subsets
710 : subset_required(indexTo);
711 :
712 : // store the from-subset-info
713 0 : SubsetInfo siFrom = m_subsetInfos[indexFrom];
714 :
715 : // store from-attachment-pipes
716 : /*VertexAttachmentPipe* apFromVrt = NULL;
717 : EdgeAttachmentPipe* apFromEdge = NULL;
718 : FaceAttachmentPipe* apFromFace = NULL;
719 : VolumeAttachmentPipe* apFromVol = NULL;
720 : if(subset_attachments_are_enabled())
721 : {
722 : apFromVrt = m_vertexAttachmentPipes[indexFrom];
723 : apFromEdge = m_edgeAttachmentPipes[indexFrom];
724 : apFromFace = m_faceAttachmentPipes[indexFrom];
725 : apFromVol = m_volumeAttachmentPipes[indexFrom];
726 : }*/
727 :
728 : // assign new indices to elements in from subset (no iterators are changed)
729 0 : change_subset_indices(indexFrom, indexTo);
730 :
731 : // move the subsets between indexFrom and indexTo
732 0 : for(int i = indexFrom; i != indexTo; i+= moveDir)
733 : {
734 0 : int iNext = i+moveDir;
735 : // assign new indices
736 0 : change_subset_indices(iNext, i);
737 :
738 : // move info
739 0 : m_subsetInfos[i] = m_subsetInfos[iNext];
740 : }
741 :
742 : // assign stored info
743 0 : m_subsetInfos[indexTo] = siFrom;
744 :
745 : // assign stored attachment pipes
746 : /*if(subset_attachments_are_enabled())
747 : {
748 : m_vertexAttachmentPipes[indexTo] = apFromVrt;
749 : m_edgeAttachmentPipes[indexTo] = apFromEdge;
750 : m_faceAttachmentPipes[indexTo] = apFromFace;
751 : m_volumeAttachmentPipes[indexTo] = apFromVol;
752 : }*/
753 :
754 : // move the subsets lists
755 0 : move_subset_lists(indexFrom, indexTo);
756 : }
757 : }
758 : else{
759 0 : UG_THROW("bad indices: " << indexFrom << ", " << indexTo);
760 : }
761 0 : }
762 :
763 0 : void ISubsetHandler::
764 : join_subsets(int targetSub, int sub1, int sub2, bool eraseUnusedSubs)
765 : {
766 : //todo: adjust attachments...
767 :
768 0 : if((sub1 < 0) || (sub1 >= num_subsets())
769 0 : || (sub2 < 0) || (sub2 >= num_subsets())
770 0 : || (targetSub < 0))
771 : {
772 0 : UG_THROW("Bad subset indices in join_subsets.");
773 : }
774 :
775 : subset_required(targetSub);
776 :
777 : // change indices. no entries are copied or lists are changed here
778 0 : if(targetSub != sub1)
779 0 : change_subset_indices(sub1, targetSub);
780 :
781 0 : if(targetSub != sub2)
782 0 : change_subset_indices(sub2, targetSub);
783 :
784 : // change lists. no indices are affected.
785 0 : join_subset_lists(targetSub, sub1, sub2);
786 :
787 0 : if(eraseUnusedSubs){
788 : // erase the two old subsets. be careful not to delete wrong subsets
789 0 : int delFirst = max(sub1, sub2);
790 0 : int delSecond = min(sub1, sub2);
791 :
792 0 : if(delFirst != targetSub)
793 0 : erase_subset(delFirst);
794 0 : if(delSecond != targetSub)
795 0 : erase_subset(delSecond);
796 : }
797 0 : }
798 :
799 : ////////////////////////////////////////////////////////////////////////
800 : // attachments
801 : /*
802 : void ISubsetHandler::
803 : resize_attachment_pipes(size_t newSize)
804 : {
805 : while(m_vertexAttachmentPipes.size() < newSize)
806 : m_vertexAttachmentPipes.push_back(new VertexAttachmentPipe(this));
807 : while(m_edgeAttachmentPipes.size() < newSize)
808 : m_edgeAttachmentPipes.push_back(new EdgeAttachmentPipe(this));
809 : while(m_faceAttachmentPipes.size() < newSize)
810 : m_faceAttachmentPipes.push_back(new FaceAttachmentPipe(this));
811 : while(m_volumeAttachmentPipes.size() < newSize)
812 : m_volumeAttachmentPipes.push_back(new VolumeAttachmentPipe(this));
813 : }
814 : */
815 : /*
816 : void ISubsetHandler::
817 : clear_attachment_pipes()
818 : {
819 : for(size_t i = 0; i < m_vertexAttachmentPipes.size(); ++i){
820 : // all pipes have the same size
821 : delete m_vertexAttachmentPipes[i];
822 : delete m_edgeAttachmentPipes[i];
823 : delete m_faceAttachmentPipes[i];
824 : delete m_volumeAttachmentPipes[i];
825 : }
826 : m_vertexAttachmentPipes.clear();
827 : m_edgeAttachmentPipes.clear();
828 : m_faceAttachmentPipes.clear();
829 : m_volumeAttachmentPipes.clear();
830 : }
831 : */
832 : /*
833 : void ISubsetHandler::
834 : clear_attachment_pipes(int subsetIndex)
835 : {
836 : m_vertexAttachmentPipes[subsetIndex]->clear();
837 : m_edgeAttachmentPipes[subsetIndex]->clear();
838 : m_faceAttachmentPipes[subsetIndex]->clear();
839 : m_volumeAttachmentPipes[subsetIndex]->clear();
840 : }
841 : */
842 : /*
843 : void ISubsetHandler::
844 : enable_subset_attachments(bool bEnable)
845 : {
846 : if(bEnable && (!subset_attachments_are_enabled()))
847 : {
848 : // LOG(" enabling...\n");
849 : // enable subset-attachments.
850 : m_bSubsetAttachmentsEnabled = true;
851 : // attach data-indices to the elements
852 : //TODO: allow subset-attachments for vertices, edges, faces and volumes separately.
853 : if(m_pGrid)
854 : {
855 : // LOG(" attaching data...\n");
856 : m_pGrid->attach_to_vertices(m_aDataIndex);
857 : m_pGrid->attach_to_edges(m_aDataIndex);
858 : m_pGrid->attach_to_faces(m_aDataIndex);
859 : m_pGrid->attach_to_volumes(m_aDataIndex);
860 : m_aaDataIndVRT.access(*m_pGrid, m_aDataIndex);
861 : m_aaDataIndEDGE.access(*m_pGrid, m_aDataIndex);
862 : m_aaDataIndFACE.access(*m_pGrid, m_aDataIndex);
863 : m_aaDataIndVOL.access(*m_pGrid, m_aDataIndex);
864 :
865 : resize_attachment_pipes(num_subsets());
866 : // tell the derived class that it should register all
867 : // of its elements at the pipe.
868 : register_subset_elements_at_pipe();
869 : }
870 : }
871 :
872 : if(!bEnable && subset_attachments_are_enabled())
873 : {
874 : if(m_pGrid)
875 : {
876 : // clear attachment data
877 : if(subset_attachments_are_enabled())
878 : {
879 : // clear pipes
880 : clear_attachment_pipes();
881 :
882 : m_pGrid->detach_from_vertices(m_aDataIndex);
883 : m_pGrid->detach_from_edges(m_aDataIndex);
884 : m_pGrid->detach_from_faces(m_aDataIndex);
885 : m_pGrid->detach_from_volumes(m_aDataIndex);
886 : }
887 :
888 : m_bSubsetAttachmentsEnabled = false;
889 : }
890 : }
891 : }
892 : */
893 : ////////////////////////////////////////////////////////////////////////
894 : // grid callbacks
895 : /*
896 : void ISubsetHandler::
897 : registered_at_grid(Grid* grid)
898 : {
899 : if(m_pGrid != NULL)
900 : m_pGrid->unregister_observer(this);
901 :
902 : m_pGrid = grid;
903 : if(m_pGrid != NULL)
904 : {
905 : // initialise attachments and accessors.
906 : // do this whith a little trick:
907 : // set the supported-element-options to SHE_NONE,
908 : // then call enable for all element-types that should be supported.
909 : uint tmpOpts = m_supportedElements;
910 : m_supportedElements = SHE_NONE;
911 : enable_element_support(tmpOpts);
912 :
913 : // enable attachments - if required
914 : if(subset_attachments_are_enabled())
915 : {
916 : m_bSubsetAttachmentsEnabled = false;
917 : enable_subset_attachments(true);
918 : }
919 :
920 : //DEBUG: log m_supportedElements
921 : //LOG("supported elements after registration: " << m_supportedElements << "\n");
922 : }
923 : }
924 :
925 : void ISubsetHandler::
926 : unregistered_from_grid(Grid* grid)
927 : {
928 : assert(m_pGrid && "this method should only be called while the handler is registered at a grid.");
929 :
930 : if(m_pGrid)
931 : {
932 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::unregistered_from_grid(...): Grids do not match.");
933 :
934 : // clear the subsets
935 : m_subsetInfos.clear();
936 :
937 : // disable all currently supported elements (this will remove any attachments)
938 : disable_element_support(m_supportedElements);
939 :
940 : // clear attachment data
941 : if(subset_attachments_are_enabled())
942 : {
943 : m_pGrid->detach_from_vertices(m_aDataIndex);
944 : m_pGrid->detach_from_edges(m_aDataIndex);
945 : m_pGrid->detach_from_faces(m_aDataIndex);
946 : m_pGrid->detach_from_volumes(m_aDataIndex);
947 :
948 : // clear pipes
949 : clear_attachment_pipes();
950 : }
951 :
952 : //DEBUG: log m_supportedElements
953 : //LOG("supported elements after deregistration: " << m_supportedElements << "\n");
954 : m_pGrid = NULL;
955 : }
956 : }
957 : */
958 0 : void ISubsetHandler::
959 : grid_to_be_destroyed(Grid* grid)
960 : {
961 : assert((m_pGrid == grid) && "ERROR in ISubsetHandler::grid_to_be_destroyed(...): Grids do not match.");
962 0 : if(m_pGrid == grid)
963 0 : set_grid(NULL);
964 0 : }
965 :
966 0 : void ISubsetHandler::
967 : elements_to_be_cleared(Grid* grid)
968 : {
969 0 : for(int si = 0; si < num_subsets(); si++)
970 0 : clear_subset_lists(si);
971 0 : }
972 :
973 : // vertex callbacks
974 0 : void ISubsetHandler::
975 : vertex_created(Grid* grid, Vertex* vrt, GridObject* pParent,
976 : bool replacesParent)
977 : {
978 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::vertex_created(...): Grids do not match.");
979 :
980 : //TODO: this if could be removed if the subset-handler was only registered for
981 : // the elements that it supports. Note that a dynamic register/unregister
982 : // would be required...
983 0 : if(elements_are_supported(SHE_VERTEX)){
984 : //LOG("new vertex...\n");
985 0 : m_aaSubsetIndexVRT[vrt] = -1;
986 : //LOG("si_before assignement: " << get_subset_index(vrt) << endl);
987 0 : if((pParent != NULL) && m_bSubsetInheritanceEnabled){
988 0 : if(m_bStrictInheritanceEnabled){
989 0 : if(pParent->base_object_id() == VERTEX){
990 0 : assign_subset(vrt, get_subset_index(
991 : reinterpret_cast<Vertex*>(pParent)));
992 : }
993 0 : else if(m_defaultSubsetIndex != -1)
994 0 : assign_subset(vrt, m_defaultSubsetIndex);
995 : }
996 : else
997 0 : assign_subset(vrt, get_subset_index(pParent));
998 : }
999 0 : else if(m_defaultSubsetIndex != -1)
1000 0 : assign_subset(vrt, m_defaultSubsetIndex);
1001 : //LOG("vertex creation done\n");
1002 : }
1003 0 : }
1004 :
1005 0 : void ISubsetHandler::
1006 : vertex_to_be_erased(Grid* grid, Vertex* vrt, Vertex* replacedBy)
1007 : {
1008 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::vertex_to_be_erased(...): Grids do not match.");
1009 :
1010 : ///TODO: see vertex_created
1011 0 : if(elements_are_supported(SHE_VERTEX)){
1012 0 : if(m_aaSubsetIndexVRT[vrt] != -1)
1013 0 : assign_subset(vrt, -1);
1014 : }
1015 0 : }
1016 :
1017 : // edge callbacks
1018 0 : void ISubsetHandler::
1019 : edge_created(Grid* grid, Edge* edge, GridObject* pParent,
1020 : bool replacesParent)
1021 : {
1022 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::edge_created(...): Grids do not match.");
1023 :
1024 : ///TODO: see vertex_created
1025 0 : if(elements_are_supported(SHE_EDGE)){
1026 0 : m_aaSubsetIndexEDGE[edge] = -1;
1027 :
1028 0 : if((pParent != NULL) && m_bSubsetInheritanceEnabled){
1029 0 : if(m_bStrictInheritanceEnabled){
1030 0 : if(pParent->base_object_id() == EDGE){
1031 0 : assign_subset(edge, get_subset_index(
1032 : reinterpret_cast<Edge*>(pParent)));
1033 : }
1034 0 : else if(m_defaultSubsetIndex != -1)
1035 0 : assign_subset(edge, m_defaultSubsetIndex);
1036 : }
1037 : else
1038 0 : assign_subset(edge, get_subset_index(pParent));
1039 : }
1040 0 : else if(m_defaultSubsetIndex != -1)
1041 0 : assign_subset(edge, m_defaultSubsetIndex);
1042 : }
1043 0 : }
1044 :
1045 0 : void ISubsetHandler::
1046 : edge_to_be_erased(Grid* grid, Edge* edge, Edge* replacedBy)
1047 : {
1048 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::edge_to_be_erased(...): Grids do not match.");
1049 :
1050 : ///TODO: see vertex_created
1051 0 : if(elements_are_supported(SHE_EDGE)){
1052 0 : if(m_aaSubsetIndexEDGE[edge] != -1)
1053 0 : assign_subset(edge, -1);
1054 : }
1055 :
1056 0 : }
1057 :
1058 : // face callbacks
1059 0 : void ISubsetHandler::
1060 : face_created(Grid* grid, Face* face, GridObject* pParent,
1061 : bool replacesParent)
1062 : {
1063 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::face_created(...): Grids do not match.");
1064 :
1065 : ///TODO: see vertex_created
1066 0 : if(elements_are_supported(SHE_FACE)){
1067 0 : m_aaSubsetIndexFACE[face] = -1;
1068 :
1069 0 : if((pParent != NULL) && m_bSubsetInheritanceEnabled){
1070 0 : if(m_bStrictInheritanceEnabled){
1071 0 : if(pParent->base_object_id() == FACE){
1072 0 : assign_subset(face, get_subset_index(
1073 : reinterpret_cast<Face*>(pParent)));
1074 : }
1075 0 : else if(m_defaultSubsetIndex != -1)
1076 0 : assign_subset(face, m_defaultSubsetIndex);
1077 : }
1078 : else
1079 0 : assign_subset(face, get_subset_index(pParent));
1080 : }
1081 0 : else if(m_defaultSubsetIndex != -1)
1082 0 : assign_subset(face, m_defaultSubsetIndex);
1083 : }
1084 0 : }
1085 :
1086 0 : void ISubsetHandler::
1087 : face_to_be_erased(Grid* grid, Face* face, Face* replacedBy)
1088 : {
1089 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::face_to_be_erased(...): Grids do not match.");
1090 :
1091 : ///TODO: see vertex_created
1092 0 : if(elements_are_supported(SHE_FACE)){
1093 0 : if(m_aaSubsetIndexFACE[face] != -1)
1094 0 : assign_subset(face, -1);
1095 : }
1096 0 : }
1097 :
1098 : // volume callbacks
1099 0 : void ISubsetHandler::
1100 : volume_created(Grid* grid, Volume* vol, GridObject* pParent,
1101 : bool replacesParent)
1102 : {
1103 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::volume_created(...): Grids do not match.");
1104 :
1105 : ///TODO: see vertex_created
1106 0 : if(elements_are_supported(SHE_VOLUME)){
1107 0 : m_aaSubsetIndexVOL[vol] = -1;
1108 :
1109 0 : if((pParent != NULL) && m_bSubsetInheritanceEnabled){
1110 0 : if(m_bStrictInheritanceEnabled){
1111 0 : if(pParent->base_object_id() == VOLUME){
1112 0 : assign_subset(vol, get_subset_index(
1113 : reinterpret_cast<Volume*>(pParent)));
1114 : }
1115 0 : else if(m_defaultSubsetIndex != -1)
1116 0 : assign_subset(vol, m_defaultSubsetIndex);
1117 : }
1118 : else
1119 0 : assign_subset(vol, get_subset_index(pParent));
1120 : }
1121 0 : else if(m_defaultSubsetIndex != -1)
1122 0 : assign_subset(vol, m_defaultSubsetIndex);
1123 : }
1124 0 : }
1125 :
1126 0 : void ISubsetHandler::
1127 : volume_to_be_erased(Grid* grid, Volume* vol, Volume* replacedBy)
1128 : {
1129 : assert((m_pGrid == grid) && "ERROR in SubsetHandler::volume_to_be_erased(...): Grids do not match.");
1130 :
1131 : ///TODO: see vertex_created
1132 0 : if(elements_are_supported(SHE_VOLUME)){
1133 0 : if(m_aaSubsetIndexVOL[vol] != -1)
1134 0 : assign_subset(vol, -1);
1135 : }
1136 0 : }
1137 :
1138 : template <class TElem>
1139 0 : void ISubsetHandler::
1140 : elems_to_be_merged(Grid* grid, TElem* target,
1141 : TElem* elem1, TElem* elem2)
1142 : {
1143 : int si1 = get_subset_index(elem1);
1144 : int si2 = get_subset_index(elem2);
1145 :
1146 : // if both subsets are -1, we'll leave everything as it was.
1147 0 : if(si1 == -1 && si2 != -1)
1148 0 : assign_subset(target, si2);
1149 0 : else if(si2 == -1 && si1 != -1)
1150 0 : assign_subset(target, si1);
1151 0 : }
1152 :
1153 0 : void ISubsetHandler::
1154 : vertices_to_be_merged(Grid* grid, Vertex* target,
1155 : Vertex* elem1, Vertex* elem2)
1156 : {
1157 0 : if(elements_are_supported(SHE_VERTEX))
1158 0 : elems_to_be_merged(grid, target, elem1, elem2);
1159 :
1160 0 : }
1161 :
1162 0 : void ISubsetHandler::
1163 : edges_to_be_merged(Grid* grid, Edge* target,
1164 : Edge* elem1, Edge* elem2)
1165 : {
1166 0 : if(elements_are_supported(SHE_EDGE))
1167 0 : elems_to_be_merged(grid, target, elem1, elem2);
1168 0 : }
1169 :
1170 0 : void ISubsetHandler::
1171 : faces_to_be_merged(Grid* grid, Face* target,
1172 : Face* elem1, Face* elem2)
1173 : {
1174 0 : if(elements_are_supported(SHE_FACE))
1175 0 : elems_to_be_merged(grid, target, elem1, elem2);
1176 0 : }
1177 :
1178 0 : void ISubsetHandler::
1179 : volumes_to_be_merged(Grid* grid, Volume* target,
1180 : Volume* elem1, Volume* elem2)
1181 : {
1182 0 : if(elements_are_supported(SHE_VOLUME))
1183 0 : elems_to_be_merged(grid, target, elem1, elem2);
1184 0 : }
1185 :
1186 : }// end of namespace
1187 :
|