Line data Source code
1 : /*
2 : * Copyright (c) 2009-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 <algorithm>
34 : #include "multi_grid.h"
35 : #include "lib_grid_messages.h"
36 :
37 : using namespace std;
38 :
39 : namespace ug
40 : {
41 :
42 0 : MultiGrid::MultiGrid() :
43 : Grid(),
44 : m_aVertexInfo("MultiGrid_VertexInfo"),
45 : m_aEdgeInfo("MultiGrid_EdgeInfo"),
46 : m_aFaceInfo("MultiGrid_FaceInfo"),
47 : m_aVolumeInfo("MultiGrid_VolumeInfo"),
48 0 : m_aParentType("MultiGrid_ParentType")
49 : {
50 0 : init();
51 0 : }
52 :
53 0 : MultiGrid::MultiGrid(uint options) :
54 : Grid(options),
55 : m_aVertexInfo("MultiGrid_VertexInfo"),
56 : m_aEdgeInfo("MultiGrid_EdgeInfo"),
57 : m_aFaceInfo("MultiGrid_FaceInfo"),
58 : m_aVolumeInfo("MultiGrid_VolumeInfo"),
59 0 : m_aParentType("MultiGrid_ParentType")
60 : {
61 0 : init();
62 0 : }
63 :
64 0 : MultiGrid::~MultiGrid()
65 : {
66 : // release child infos
67 0 : for(FaceIterator iter = begin<Face>(); iter != end<Face>(); ++iter)
68 0 : release_child_info(*iter);
69 :
70 0 : for(VolumeIterator iter = begin<Volume>(); iter != end<Volume>(); ++iter)
71 0 : release_child_info(*iter);
72 0 : }
73 :
74 0 : void MultiGrid::init()
75 : {
76 : // the subset-handler that manages the hierarchy
77 : // has to be registered before the multi-grid (order of create-methods).
78 0 : m_hierarchy.assign_grid(*this);
79 0 : m_hierarchy.enable_subset_inheritance(false);
80 0 : m_bHierarchicalInsertion = true;
81 :
82 : // the MultiGrid observes itself (its underlying grid).
83 0 : register_observer(this, OT_VERTEX_OBSERVER | OT_EDGE_OBSERVER |
84 : OT_FACE_OBSERVER | OT_VOLUME_OBSERVER);
85 :
86 : // attach parent-pointers
87 0 : attach_to_faces(m_aParent);
88 : attach_to_volumes(m_aParent);
89 :
90 : // attach elem-infos
91 0 : attach_to_vertices(m_aVertexInfo);
92 0 : attach_to_edges(m_aEdgeInfo);
93 0 : attach_to_faces_dv(m_aFaceInfo, NULL);
94 0 : attach_to_volumes_dv(m_aVolumeInfo, NULL);
95 :
96 0 : attach_to_all(m_aParentType);
97 :
98 : // init accessors
99 0 : m_aaVrtInf.access(*this, m_aVertexInfo);
100 0 : m_aaEdgeInf.access(*this, m_aEdgeInfo);
101 : m_aaFaceInf.access(*this, m_aFaceInfo);
102 0 : m_aaParentFACE.access(*this, m_aParent);
103 : m_aaVolInf.access(*this, m_aVolumeInfo);
104 : m_aaParentVOL.access(*this, m_aParent);
105 :
106 0 : m_aaParentType.access(*this, m_aParentType, true, true, true, true);
107 0 : }
108 :
109 0 : void MultiGrid::create_levels(int numLevels)
110 : {
111 0 : for(int i = 0; i < numLevels; ++i){
112 : // inform the hierarchy handler, that one level has to be added
113 0 : m_hierarchy.subset_required(num_levels());
114 : // send a message, that a new level has been created
115 0 : message_hub()->post_message(
116 0 : GridMessage_MultiGridChanged(GMMGCT_LEVEL_ADDED, num_levels()));
117 : }
118 0 : }
119 :
120 0 : void MultiGrid::enable_hierarchical_insertion(bool bEnable)
121 : {
122 0 : m_bHierarchicalInsertion = bEnable;
123 0 : }
124 :
125 : ////////////////////////////////////////////////////////////////////////
126 : // create methods
127 0 : VertexIterator MultiGrid::
128 : create_by_cloning(Vertex* pCloneMe, int level)
129 : {
130 0 : VertexIterator iter = Grid::create_by_cloning(pCloneMe);
131 : // put the element into the hierarchy
132 : // (by default it already was assigned to level 0)
133 0 : if(level > 0){
134 : level_required(level);
135 0 : m_hierarchy.assign_subset(*iter, level);
136 : }
137 0 : return iter;
138 : }
139 :
140 0 : EdgeIterator MultiGrid::
141 : create_by_cloning(Edge* pCloneMe, const EdgeVertices& ev, int level)
142 : {
143 0 : EdgeIterator iter = Grid::create_by_cloning(pCloneMe, ev);
144 : // put the element into the hierarchy
145 : // (by default it already was assigned to level 0)
146 0 : if(level > 0){
147 : level_required(level);
148 0 : m_hierarchy.assign_subset(*iter, level);
149 : }
150 0 : return iter;
151 : }
152 :
153 0 : FaceIterator MultiGrid::
154 : create_by_cloning(Face* pCloneMe, const FaceVertices& fv, int level)
155 : {
156 0 : FaceIterator iter = Grid::create_by_cloning(pCloneMe, fv);
157 : // put the element into the hierarchy
158 : // (by default it already was assigned to level 0)
159 0 : if(level > 0){
160 : level_required(level);
161 0 : m_hierarchy.assign_subset(*iter, level);
162 : }
163 0 : return iter;
164 : }
165 :
166 0 : VolumeIterator MultiGrid::
167 : create_by_cloning(Volume* pCloneMe, const VolumeVertices& vv, int level)
168 : {
169 0 : VolumeIterator iter = Grid::create_by_cloning(pCloneMe, vv);
170 : // put the element into the hierarchy
171 : // (by default it already was assigned to level 0)
172 0 : if(level > 0){
173 : level_required(level);
174 0 : m_hierarchy.assign_subset(*iter, level);
175 : }
176 0 : return iter;
177 : }
178 :
179 :
180 0 : GridObject* MultiGrid::get_parent(GridObject* parent) const
181 : {
182 0 : int baseType = parent->base_object_id();
183 0 : switch(baseType)
184 : {
185 0 : case VERTEX: return get_parent((Vertex*)parent);
186 0 : case EDGE: return get_parent((Edge*)parent);
187 0 : case FACE: return get_parent((Face*)parent);
188 0 : case VOLUME: return get_parent((Volume*)parent);
189 : }
190 : return NULL;
191 : }
192 :
193 : ////////////////////////////////////////////////////////////////////////
194 : // grid-observer callbacks
195 :
196 0 : void MultiGrid::elements_to_be_cleared(Grid* grid)
197 : {
198 : //TODO: runtime of clear can be optimized in this method.
199 0 : }
200 :
201 : // vertices
202 0 : void MultiGrid::vertex_created(Grid* grid, Vertex* vrt,
203 : GridObject* pParent,
204 : bool replacesParent)
205 : {
206 : // if hierarchical_insertion is disabled, the elemenet is inserted
207 : // into the same level as its parent.
208 : // From the standpoint of a multigrid-hierarchy it thus makes sense
209 : // to make pParents parent the parent of elem!!!
210 :
211 0 : if(replacesParent){
212 : // the object given in parent will be replaced be the newly created one.
213 : // The parent of pParent is thus the real parent of the new object.
214 : UG_ASSERT(pParent, "A parent has to exist if it shall be replaced.");
215 : UG_ASSERT(pParent->base_object_id() == VERTEX,
216 : "only objects of the same base type can be replaced.");
217 : Vertex* pReplaceMe = static_cast<Vertex*>(pParent);
218 : GridObject* realParent = get_parent(pReplaceMe);
219 :
220 : // we call a version of element_created, which allows a replace
221 0 : if(realParent){
222 0 : int baseType = realParent->base_object_id();
223 0 : switch(baseType)
224 : {
225 0 : case VERTEX: element_created(vrt, (Vertex*)realParent, pReplaceMe); break;
226 0 : case EDGE: element_created(vrt, (Edge*)realParent, pReplaceMe); break;
227 0 : case FACE: element_created(vrt, (Face*)realParent, pReplaceMe); break;
228 0 : case VOLUME: element_created(vrt, (Volume*)realParent, pReplaceMe); break;
229 : }
230 : }
231 : else
232 0 : element_created<Vertex, Vertex>(vrt, NULL, pReplaceMe);
233 :
234 : // copy pReplaceMe's children and replace parent of children
235 : MGVertexInfo& myInfo = get_info(vrt);
236 : MGVertexInfo& replaceInfo = get_info(pReplaceMe);
237 :
238 0 : if(replaceInfo.child_vertex()){
239 : myInfo.add_child(replaceInfo.child_vertex());
240 : set_parent(replaceInfo.child_vertex(), vrt);
241 : set_parent_type(replaceInfo.child_vertex(), VERTEX);
242 : }
243 : }
244 : else{
245 0 : if(!hierarchical_insertion_enabled() && pParent)
246 0 : pParent = get_parent(pParent);
247 :
248 0 : if(pParent)
249 : {
250 0 : int baseType = pParent->base_object_id();
251 0 : switch(baseType)
252 : {
253 0 : case VERTEX: element_created(vrt, (Vertex*)pParent); break;
254 0 : case EDGE: element_created(vrt, (Edge*)pParent); break;
255 0 : case FACE: element_created(vrt, (Face*)pParent); break;
256 0 : case VOLUME: element_created(vrt, (Volume*)pParent); break;
257 : }
258 : }
259 : else
260 : element_created(vrt);
261 : }
262 0 : }
263 :
264 0 : void MultiGrid::vertex_to_be_erased(Grid* grid, Vertex* vrt,
265 : Vertex* replacedBy)
266 : {
267 : // if replacedBy != NULL, then vertex_created already handled the
268 : // deregistration at the parent.
269 0 : if(replacedBy)
270 : return;
271 :
272 : GridObject* pParent = get_parent(vrt);
273 0 : if(pParent)
274 : {
275 0 : int baseType = pParent->base_object_id();
276 0 : switch(baseType)
277 : {
278 0 : case VERTEX: element_to_be_erased(vrt, (Vertex*)pParent); break;
279 0 : case EDGE: element_to_be_erased(vrt, (Edge*)pParent); break;
280 0 : case FACE: element_to_be_erased(vrt, (Face*)pParent); break;
281 0 : case VOLUME: element_to_be_erased(vrt, (Volume*)pParent); break;
282 : }
283 : }
284 : else
285 : element_to_be_erased(vrt);
286 : }
287 :
288 : // edges
289 0 : void MultiGrid::edge_created(Grid* grid, Edge* edge,
290 : GridObject* pParent,
291 : bool replacesParent)
292 : {
293 0 : if(replacesParent){
294 : // the object given in parent will be replaced be the newly created one.
295 : // The parent of pParent is thus the real parent of the new object.
296 : UG_ASSERT(pParent, "A parent has to exist if it shall be replaced.");
297 : UG_ASSERT(pParent->base_object_id() == EDGE,
298 : "only objects of the same base type can be replaced.");
299 : Edge* pReplaceMe = static_cast<Edge*>(pParent);
300 : GridObject* realParent = get_parent(pReplaceMe);
301 0 : if(realParent){
302 : // we call a version of element_created, which allows a replace
303 0 : int baseType = realParent->base_object_id();
304 0 : switch(baseType)
305 : {
306 0 : case EDGE: element_created(edge, (Edge*)realParent, pReplaceMe); break;
307 0 : case FACE: element_created(edge, (Face*)realParent, pReplaceMe); break;
308 0 : case VOLUME: element_created(edge, (Volume*)realParent, pReplaceMe); break;
309 : }
310 : }
311 : else
312 0 : element_created<Edge, Edge>(edge, NULL, pReplaceMe);
313 :
314 : // copy pReplaceMes children and replace parent of children
315 : MGEdgeInfo& myInfo = get_info(edge);
316 : MGEdgeInfo& replaceInfo = get_info(pReplaceMe);
317 :
318 0 : if(replaceInfo.child_vertex()){
319 : myInfo.add_child(replaceInfo.child_vertex());
320 : set_parent(replaceInfo.child_vertex(), edge);
321 : set_parent_type(replaceInfo.child_vertex(), EDGE);
322 : }
323 :
324 0 : for(size_t i = 0; i < replaceInfo.num_child_edges(); ++i){
325 : myInfo.add_child(replaceInfo.child_edge(i));
326 : set_parent(replaceInfo.child_edge(i), edge);
327 : set_parent_type(replaceInfo.child_edge(i), EDGE);
328 : }
329 : }
330 : else{
331 0 : if(!hierarchical_insertion_enabled() && pParent)
332 0 : pParent = get_parent(pParent);
333 :
334 0 : if(pParent)
335 : {
336 0 : int baseType = pParent->base_object_id();
337 0 : switch(baseType)
338 : {
339 0 : case EDGE: element_created(edge, (Edge*)pParent); break;
340 0 : case FACE: element_created(edge, (Face*)pParent); break;
341 0 : case VOLUME: element_created(edge, (Volume*)pParent); break;
342 : }
343 : }
344 : else
345 : element_created(edge);
346 : }
347 0 : }
348 :
349 0 : void MultiGrid::edge_to_be_erased(Grid* grid, Edge* edge,
350 : Edge* replacedBy)
351 : {
352 0 : if(replacedBy)
353 : return;
354 :
355 : GridObject* pParent = get_parent(edge);
356 0 : if(pParent)
357 : {
358 0 : int baseType = pParent->base_object_id();
359 0 : switch(baseType)
360 : {
361 0 : case EDGE: element_to_be_erased(edge, (Edge*)pParent); break;
362 0 : case FACE: element_to_be_erased(edge, (Face*)pParent); break;
363 0 : case VOLUME: element_to_be_erased(edge, (Volume*)pParent); break;
364 : }
365 : }
366 : else
367 0 : element_to_be_erased(edge);
368 : }
369 :
370 : // faces
371 0 : void MultiGrid::face_created(Grid* grid, Face* face,
372 : GridObject* pParent,
373 : bool replacesParent)
374 : {
375 0 : if(replacesParent){
376 : // the object given in parent will be replaced be the newly created one.
377 : // The parent of pParent is thus the real parent of the new object.
378 : UG_ASSERT(pParent, "A parent has to exist if it shall be replaced.");
379 : UG_ASSERT(pParent->base_object_id() == FACE,
380 : "only objects of the same base type can be replaced.");
381 : Face* pReplaceMe = static_cast<Face*>(pParent);
382 : GridObject* realParent = get_parent(pReplaceMe);
383 :
384 : // we call a version of element_created, which allows a replace
385 0 : if(realParent){
386 0 : int baseType = realParent->base_object_id();
387 0 : switch(baseType)
388 : {
389 0 : case FACE: element_created(face, (Face*)realParent, pReplaceMe); break;
390 0 : case VOLUME: element_created(face, (Volume*)realParent, pReplaceMe); break;
391 : }
392 : }
393 : else
394 0 : element_created<Face, Face>(face, NULL, pReplaceMe);
395 :
396 : // copy pReplaceMes children and replace parent of children
397 : if(has_children(pReplaceMe)){
398 0 : create_child_info(face);
399 0 : MGFaceInfo& myInfo = get_info(face);
400 0 : MGFaceInfo& replaceInfo = get_info(pReplaceMe);
401 :
402 0 : if(replaceInfo.child_vertex()){
403 : myInfo.add_child(replaceInfo.child_vertex());
404 : set_parent(replaceInfo.child_vertex(), face);
405 : set_parent_type(replaceInfo.child_vertex(), FACE);
406 : }
407 :
408 0 : for(size_t i = 0; i < replaceInfo.num_child_edges(); ++i){
409 : myInfo.add_child(replaceInfo.child_edge(i));
410 : set_parent(replaceInfo.child_edge(i), face);
411 : set_parent_type(replaceInfo.child_edge(i), FACE);
412 : }
413 :
414 0 : for(size_t i = 0; i < replaceInfo.num_child_faces(); ++i){
415 : myInfo.add_child(replaceInfo.child_face(i));
416 : set_parent(replaceInfo.child_face(i), face);
417 : set_parent_type(replaceInfo.child_face(i), FACE);
418 : }
419 : }
420 : }
421 : else{
422 0 : if(!hierarchical_insertion_enabled() && pParent)
423 0 : pParent = get_parent(pParent);
424 :
425 0 : if(pParent)
426 : {
427 0 : int baseType = pParent->base_object_id();
428 0 : switch(baseType)
429 : {
430 0 : case FACE: element_created(face, (Face*)pParent); break;
431 0 : case VOLUME: element_created(face, (Volume*)pParent); break;
432 : }
433 : }
434 : else
435 : element_created(face);
436 : }
437 0 : }
438 :
439 0 : void MultiGrid::face_to_be_erased(Grid* grid, Face* face,
440 : Face* replacedBy)
441 : {
442 0 : if(replacedBy)
443 : return;
444 :
445 : GridObject* pParent = get_parent(face);
446 0 : if(pParent)
447 : {
448 0 : int baseType = pParent->base_object_id();
449 0 : switch(baseType)
450 : {
451 0 : case FACE: element_to_be_erased(face, (Face*)pParent); break;
452 0 : case VOLUME: element_to_be_erased(face, (Volume*)pParent); break;
453 : }
454 : }
455 : else
456 0 : element_to_be_erased(face);
457 : }
458 :
459 : // volumes
460 0 : void MultiGrid::volume_created(Grid* grid, Volume* vol,
461 : GridObject* pParent,
462 : bool replacesParent)
463 : {
464 0 : if(replacesParent){
465 : // the object given in parent will be replaced be the newly created one.
466 : // The parent of pParent is thus the real parent of the new object.
467 : UG_ASSERT(pParent, "A parent has to exist if it shall be replaced.");
468 : UG_ASSERT(pParent->base_object_id() == VOLUME,
469 : "only objects of the same base type can be replaced.");
470 : Volume* pReplaceMe = static_cast<Volume*>(pParent);
471 : GridObject* realParent = get_parent(pReplaceMe);
472 :
473 : // we call a version of element_created, which allows a replace
474 0 : element_created(vol, (Volume*)realParent, pReplaceMe);
475 :
476 : // copy pReplaceMes children and replace parent of children
477 0 : if(has_children(pReplaceMe)){
478 0 : create_child_info(vol);
479 0 : MGVolumeInfo& myInfo = get_info(vol);
480 0 : MGVolumeInfo& replaceInfo = get_info(pReplaceMe);
481 :
482 0 : if(replaceInfo.child_vertex()){
483 : myInfo.add_child(replaceInfo.child_vertex());
484 : set_parent(replaceInfo.child_vertex(), vol);
485 : set_parent_type(replaceInfo.child_vertex(), VOLUME);
486 : }
487 :
488 0 : for(size_t i = 0; i < replaceInfo.num_child_edges(); ++i){
489 0 : myInfo.add_child(replaceInfo.child_edge(i));
490 : set_parent(replaceInfo.child_edge(i), vol);
491 : set_parent_type(replaceInfo.child_edge(i), VOLUME);
492 : }
493 :
494 0 : for(size_t i = 0; i < replaceInfo.num_child_faces(); ++i){
495 0 : myInfo.add_child(replaceInfo.child_face(i));
496 : set_parent(replaceInfo.child_face(i), vol);
497 : set_parent_type(replaceInfo.child_face(i), VOLUME);
498 : }
499 :
500 0 : for(size_t i = 0; i < replaceInfo.num_child_volumes(); ++i){
501 0 : myInfo.add_child(replaceInfo.child_volume(i));
502 : set_parent(replaceInfo.child_volume(i), vol);
503 : set_parent_type(replaceInfo.child_volume(i), VOLUME);
504 : }
505 : }
506 : }
507 : else{
508 0 : if(!hierarchical_insertion_enabled() && pParent)
509 0 : pParent = get_parent(pParent);
510 :
511 0 : if(pParent)
512 : {
513 : UG_ASSERT(pParent->base_object_id() == VOLUME,
514 : "Only volumes can be parents to volumes.");
515 0 : element_created(vol, (Volume*)pParent);
516 : }
517 : else
518 : element_created(vol);
519 : }
520 0 : }
521 :
522 0 : void MultiGrid::volume_to_be_erased(Grid* grid, Volume* vol,
523 : Volume* replacedBy)
524 : {
525 0 : if(replacedBy)
526 : return;
527 :
528 : GridObject* pParent = get_parent(vol);
529 0 : if(pParent)
530 : {
531 : UG_ASSERT(pParent->base_object_id() == VOLUME,
532 : "Only volumes can be parents to volumes.");
533 0 : element_to_be_erased(vol, (Volume*)pParent);
534 : }
535 : else
536 0 : element_to_be_erased(vol);
537 : }
538 :
539 :
540 0 : void MultiGrid::check_edge_elem_infos(int level) const
541 : {
542 : // check the max fill rates of each child list.
543 0 : size_t maxChildEdges = 0;
544 :
545 0 : for(ConstEdgeIterator iter = begin<Edge>(level);
546 0 : iter != end<Edge>(level); ++iter)
547 0 : maxChildEdges = max(get_info(*iter).num_child_edges(), maxChildEdges);
548 :
549 0 : UG_LOG("MultiGrid: max edge child edges on level " << level << ": " << (int)maxChildEdges << endl);
550 0 : }
551 :
552 0 : void MultiGrid::check_face_elem_infos(int level) const
553 : {
554 : // check the max fill rates of each child list.
555 0 : size_t maxChildEdges = 0;
556 0 : size_t maxChildFaces = 0;
557 :
558 0 : for(ConstFaceIterator iter = begin<Face>(level);
559 0 : iter != end<Face>(level); ++iter)
560 : {
561 0 : maxChildEdges = max(get_info(*iter).num_child_edges(), maxChildEdges);
562 0 : maxChildFaces = max(get_info(*iter).num_child_faces(), maxChildFaces);
563 : }
564 :
565 0 : UG_LOG("MultiGrid: max face child edges on level " << level << ": " << (int)maxChildEdges << endl);
566 0 : UG_LOG("MultiGrid: max face child faces on level " << level << ": " << (int)maxChildFaces << endl);
567 0 : }
568 :
569 0 : void MultiGrid::check_volume_elem_infos(int level) const
570 : {
571 : // check the max fill rates of each child list.
572 0 : size_t maxChildEdges = 0;
573 0 : size_t maxChildFaces = 0;
574 0 : size_t maxChildVolumes = 0;
575 :
576 0 : for(ConstVolumeIterator iter = begin<Volume>(level);
577 0 : iter != end<Volume>(level); ++iter)
578 : {
579 0 : maxChildEdges = max(get_info(*iter).num_child_edges(), maxChildEdges);
580 0 : maxChildFaces = max(get_info(*iter).num_child_faces(), maxChildFaces);
581 0 : maxChildVolumes = max(get_info(*iter).num_child_volumes(), maxChildVolumes);
582 : }
583 :
584 0 : UG_LOG("MultiGrid: max volume child edges on level " << level << ": " << (int)maxChildEdges << endl);
585 0 : UG_LOG("MultiGrid: max volume child faces on level " << level << ": " << (int)maxChildFaces << endl);
586 0 : UG_LOG("MultiGrid: max volume child volumes on level " << level << ": " << (int)maxChildVolumes << endl);
587 0 : }
588 :
589 :
590 :
591 : ////////////////////////////////////////////////////////////////////////
592 : ////////////////////////////////////////////////////////////////////////
593 : // implementation of Info-Classes
594 0 : void MGVertexInfo::unregister_from_children(MultiGrid& mg)
595 : {
596 0 : if(m_pVrtChild)
597 : mg.set_parent(m_pVrtChild, NULL);
598 : clear_children();
599 0 : }
600 :
601 0 : void MGEdgeInfo::unregister_from_children(MultiGrid& mg)
602 : {
603 0 : if(m_pVrtChild)
604 : mg.set_parent(m_pVrtChild, NULL);
605 0 : for(int i = 0; i < m_numEdgeChildren; ++i)
606 0 : mg.set_parent(m_pEdgeChild[i], NULL);
607 : clear_children();
608 0 : }
609 :
610 0 : void MGFaceInfo::unregister_from_children(MultiGrid& mg)
611 : {
612 0 : if(m_pVrtChild)
613 : mg.set_parent(m_pVrtChild, NULL);
614 0 : for(int i = 0; i < m_numEdgeChildren; ++i)
615 0 : mg.set_parent(m_pEdgeChild[i], NULL);
616 0 : for(int i = 0; i < m_numFaceChildren; ++i)
617 0 : mg.set_parent(m_pFaceChild[i], NULL);
618 : clear_children();
619 0 : }
620 :
621 0 : void MGVolumeInfo::unregister_from_children(MultiGrid& mg)
622 : {
623 0 : if(m_pVrtChild)
624 : mg.set_parent(m_pVrtChild, NULL);
625 0 : for(size_t i = 0; i < m_edgeChildren.size(); ++i)
626 0 : mg.set_parent(m_edgeChildren[i], NULL);
627 0 : for(size_t i = 0; i < m_faceChildren.size(); ++i)
628 0 : mg.set_parent(m_faceChildren[i], NULL);
629 0 : for(size_t i = 0; i < m_volumeChildren.size(); ++i)
630 0 : mg.set_parent(m_volumeChildren[i], NULL);
631 0 : clear_children();
632 0 : }
633 :
634 : }// end of namespace
|