Line data Source code
1 : /*
2 : * Copyright (c) 2012-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__LIB_GRID__TOOLS__SURFACE_VIEW_IMPL__
34 : #define __H__UG__LIB_GRID__TOOLS__SURFACE_VIEW_IMPL__
35 :
36 : namespace ug{
37 :
38 : ////////////////////////////////////////////////////////////////////////////////
39 : // implementation of SurfaceViewElementIterator
40 : ////////////////////////////////////////////////////////////////////////////////
41 :
42 : template <class TElem>
43 0 : SurfaceView::SurfaceViewElementIterator<TElem>::
44 : SurfaceViewElementIterator(bool start,
45 : SurfaceView* sv,
46 : const GridLevel& gl,
47 : SurfaceState validStates,
48 : int si) :
49 0 : m_pSurfView(sv),
50 0 : m_gl(gl),
51 : m_validStates(validStates),
52 :
53 0 : m_fromSI( (si >= 0) ? si : 0 ),
54 0 : m_toSI( (si >= 0) ? si : (sv->subset_handler()->num_subsets() - 1) ),
55 0 : m_si(start ? m_fromSI : m_toSI),
56 :
57 0 : m_topLvl(gl.top() ? (sv->subset_handler()->num_levels()-1) : gl.level()),
58 0 : m_lvl((start && gl.is_surface() && sv->is_adaptive()) ? 0 : m_topLvl),
59 :
60 0 : m_elemIter(start ? sv->subset_handler()->begin<TElem>(m_si, m_lvl)
61 : : sv->subset_handler()->end<TElem>(m_toSI, m_topLvl)),
62 0 : m_iterEndSection(sv->subset_handler()->end<TElem>(m_si, m_lvl))
63 :
64 : {
65 : UG_ASSERT(m_topLvl >= 0 && m_topLvl < (int)sv->subset_handler()->num_levels(),
66 : "Invalid level: "<<m_topLvl<<" [min: 0, max: "<<sv->subset_handler()->num_levels()<<"]");
67 : UG_ASSERT(m_lvl >= 0 && m_lvl < (int)sv->subset_handler()->num_levels(),
68 : "Invalid level: "<<m_lvl<<" [min: 0, max: "<<sv->subset_handler()->num_levels()<<"]");
69 : UG_ASSERT(m_si >= 0 && m_si < sv->subset_handler()->num_subsets(),
70 : "Invalid subset: "<<m_si<<" [min: 0, max: "<<sv->subset_handler()->num_subsets()<<"]");
71 : UG_ASSERT(m_toSI >= 0 && m_toSI < sv->subset_handler()->num_subsets(),
72 : "Invalid subset: "<<m_toSI<<" [min: 0, max: "<<sv->subset_handler()->num_subsets()<<"]");
73 :
74 : // if at end of section -> increase until next non-empty section
75 0 : if(m_elemIter == m_iterEndSection)
76 0 : if(!increment_section())
77 : return;
78 :
79 : // m_elemIter has to point to a valid surface view element
80 0 : if(!is_contained(*m_elemIter)){increment(); return;}
81 : }
82 :
83 : template <class TElem>
84 : SurfaceView::SurfaceViewElementIterator<TElem>::
85 : SurfaceViewElementIterator() :
86 : m_pSurfView(NULL),
87 : m_gl(),
88 : m_validStates(0),
89 : m_fromSI(0),
90 : m_toSI(0),
91 : m_si(0),
92 : m_topLvl(0),
93 : m_lvl(0),
94 : m_elemIter(),
95 : m_iterEndSection()
96 : {}
97 :
98 : template <class TElem>
99 : bool SurfaceView::SurfaceViewElementIterator<TElem>::
100 : equal(SurfaceView::SurfaceViewElementIterator<TElem> const& other) const
101 : {
102 : return (m_elemIter == other.m_elemIter);
103 : }
104 :
105 : template <class TElem>
106 0 : bool SurfaceView::SurfaceViewElementIterator<TElem>::
107 : increment_section()
108 : {
109 : // check if end of section reached
110 : do
111 : {
112 : // a) if still subsets left to loop on level
113 0 : if(m_si < m_toSI)
114 : {
115 : // increase subset, set new section iterators
116 0 : ++m_si;
117 0 : m_elemIter = m_pSurfView->subset_handler()->begin<TElem>(m_si, m_lvl);
118 0 : m_iterEndSection = m_pSurfView->subset_handler()->end<TElem>(m_si, m_lvl);
119 : }
120 : // b) if still levels left to be looped
121 0 : else if(m_lvl < m_topLvl)
122 : {
123 : // increase level, reset subset to fromSubset, set new section iterators
124 0 : ++m_lvl;
125 0 : m_si = m_fromSI;
126 0 : m_elemIter = m_pSurfView->subset_handler()->begin<TElem>(m_si, m_lvl);
127 0 : m_iterEndSection = m_pSurfView->subset_handler()->end<TElem>(m_si, m_lvl);
128 : }
129 : // c) no section left, we're done (m_elemIter is end iterator now)
130 : else {
131 : return false;
132 : }
133 : }
134 0 : while(m_elemIter == m_iterEndSection);
135 : return true;
136 : }
137 :
138 : template <class TElem>
139 0 : void SurfaceView::SurfaceViewElementIterator<TElem>::
140 : increment()
141 : {
142 : // we search the next non-shadowed element
143 : do
144 : {
145 : // increase iterator
146 : ++m_elemIter;
147 :
148 : // check if end of section reached
149 0 : if(m_elemIter == m_iterEndSection){
150 0 : if(!increment_section())
151 : return;
152 : }
153 :
154 0 : }while(!is_contained(*m_elemIter));
155 : }
156 :
157 : template <class TElem>
158 : typename SurfaceView::SurfaceViewElementIterator<TElem>::TValue
159 : SurfaceView::SurfaceViewElementIterator<TElem>::
160 : dereference() const
161 : {
162 : return *m_elemIter;
163 : }
164 :
165 : template <class TElem>
166 : template <class TGeomObj>
167 : bool SurfaceView::SurfaceViewElementIterator<TElem>::
168 : is_contained(TGeomObj* obj) const
169 : {
170 : #ifdef UG_PARALLEL
171 : if(m_pSurfView->is_ghost(obj)){
172 : if(m_gl.ghosts() && (m_lvl == m_topLvl)) return true;
173 : else return false;
174 : }
175 : #endif
176 :
177 0 : SurfaceState oss = m_pSurfView->surface_state(obj);
178 :
179 : if( m_validStates.contains(TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE)
180 0 : && (m_lvl == m_topLvl)
181 0 : && oss.partially_contains(MG_SHADOW))
182 : {
183 : oss = MG_SURFACE_PURE;
184 : }
185 :
186 : return m_validStates.contains(oss);
187 : }
188 :
189 :
190 : ////////////////////////////////////////////////////////////////////////////////
191 : // implementation of ConstSurfaceViewElementIterator
192 : ////////////////////////////////////////////////////////////////////////////////
193 :
194 : template <class TElem>
195 0 : SurfaceView::ConstSurfaceViewElementIterator<TElem>::
196 : ConstSurfaceViewElementIterator(const SurfaceView::SurfaceViewElementIterator<TElem>& iter)
197 : {
198 0 : m_pSurfView = iter.m_pSurfView;
199 0 : m_gl = iter.m_gl;
200 : m_validStates = iter.m_validStates;
201 0 : m_fromSI = iter.m_fromSI;
202 0 : m_toSI = iter.m_toSI;
203 0 : m_si = iter.m_si;
204 0 : m_topLvl = iter.m_topLvl;
205 0 : m_lvl = iter.m_lvl;
206 : m_elemIter = iter.m_elemIter;
207 : m_iterEndSection = iter.m_iterEndSection;
208 0 : }
209 :
210 : template <class TElem>
211 0 : SurfaceView::ConstSurfaceViewElementIterator<TElem>::
212 : ConstSurfaceViewElementIterator() :
213 0 : m_pSurfView(0),
214 : m_gl(),
215 : m_validStates(0),
216 0 : m_fromSI(0),
217 0 : m_toSI(0),
218 0 : m_si(0),
219 0 : m_topLvl(0),
220 0 : m_lvl(0),
221 : m_elemIter(),
222 : m_iterEndSection()
223 : {}
224 :
225 : template <class TElem>
226 0 : SurfaceView::ConstSurfaceViewElementIterator<TElem>::
227 : ConstSurfaceViewElementIterator(bool start,
228 : const SurfaceView* sv,
229 : const GridLevel& gl,
230 : SurfaceState validStates,
231 : int si) :
232 0 : m_pSurfView(sv),
233 0 : m_gl(gl),
234 : m_validStates(validStates),
235 :
236 0 : m_fromSI( (si >= 0) ? si : 0 ),
237 0 : m_toSI( (si >= 0) ? si : (sv->subset_handler()->num_subsets() - 1) ),
238 0 : m_si(start ? m_fromSI : m_toSI),
239 :
240 0 : m_topLvl(gl.top() ? (sv->subset_handler()->num_levels()-1) : gl.level()),
241 0 : m_lvl((start && gl.is_surface() && sv->is_adaptive()) ? 0 : m_topLvl),
242 :
243 0 : m_elemIter(start ? sv->subset_handler()->begin<TElem>(m_si, m_lvl)
244 : : sv->subset_handler()->end<TElem>(m_toSI, m_topLvl)),
245 0 : m_iterEndSection(sv->subset_handler()->end<TElem>(m_si, m_lvl))
246 :
247 : {
248 : UG_ASSERT(m_topLvl >= 0 && m_topLvl < (int)sv->subset_handler()->num_levels(),
249 : "Invalid level: "<<m_topLvl<<" [min: 0, max: "<<sv->subset_handler()->num_levels()<<"]");
250 : UG_ASSERT(m_lvl >= 0 && m_lvl < (int)sv->subset_handler()->num_levels(),
251 : "Invalid level: "<<m_lvl<<" [min: 0, max: "<<sv->subset_handler()->num_levels()<<"]");
252 : UG_ASSERT(m_si >= 0 && m_si < sv->subset_handler()->num_subsets(),
253 : "Invalid subset: "<<m_si<<" [min: 0, max: "<<sv->subset_handler()->num_subsets()<<"]");
254 : UG_ASSERT(m_toSI >= 0 && m_toSI < sv->subset_handler()->num_subsets(),
255 : "Invalid subset: "<<m_toSI<<" [min: 0, max: "<<sv->subset_handler()->num_subsets()<<"]");
256 :
257 : // if at end of section -> increase until next non-empty section
258 0 : if(m_elemIter == m_iterEndSection)
259 0 : if(!increment_section())
260 : return;
261 :
262 : // m_elemIter has to point to a valid surface view element
263 0 : if(!is_contained(*m_elemIter)){increment(); return;}
264 : }
265 :
266 : template <class TElem>
267 : bool SurfaceView::ConstSurfaceViewElementIterator<TElem>::
268 : equal(SurfaceView::ConstSurfaceViewElementIterator<TElem> const& other) const
269 : {
270 : return (m_elemIter == other.m_elemIter);
271 : }
272 :
273 : template <class TElem>
274 0 : bool SurfaceView::ConstSurfaceViewElementIterator<TElem>::
275 : increment_section()
276 : {
277 : // check if end of section reached
278 : do
279 : {
280 : // a) if still subsets left to loop on level
281 0 : if(m_si < m_toSI)
282 : {
283 : // increase subset, set new section iterators
284 0 : ++m_si;
285 0 : m_elemIter = m_pSurfView->subset_handler()->begin<TElem>(m_si, m_lvl);
286 0 : m_iterEndSection = m_pSurfView->subset_handler()->end<TElem>(m_si, m_lvl);
287 : }
288 : // b) if still levels left to be looped
289 0 : else if(m_lvl < m_topLvl)
290 : {
291 : // increase level, reset subset to fromSubset, set new section iterators
292 0 : ++m_lvl;
293 0 : m_si = m_fromSI;
294 0 : m_elemIter = m_pSurfView->subset_handler()->begin<TElem>(m_si, m_lvl);
295 0 : m_iterEndSection = m_pSurfView->subset_handler()->end<TElem>(m_si, m_lvl);
296 : }
297 : // c) no section left, we're done (m_elemIter is end iterator now)
298 : else {
299 : return false;
300 : }
301 : }
302 0 : while(m_elemIter == m_iterEndSection);
303 : return true;
304 : }
305 :
306 : template <class TElem>
307 0 : void SurfaceView::ConstSurfaceViewElementIterator<TElem>::
308 : increment()
309 : {
310 : // this iterator should only be enabled for optimization work
311 : // PROFILE_FUNC_GROUP("SurfaceView::iterator")
312 : // we search the next non-shadowed element
313 : do
314 : {
315 : // increase iterator
316 : ++m_elemIter;
317 :
318 : // check if end of section reached
319 0 : if(m_elemIter == m_iterEndSection){
320 0 : if(!increment_section())
321 : return;
322 : }
323 0 : }while(!is_contained(*m_elemIter));
324 : }
325 :
326 : template <class TElem>
327 : typename SurfaceView::ConstSurfaceViewElementIterator<TElem>::TValue
328 : SurfaceView::ConstSurfaceViewElementIterator<TElem>::
329 : dereference() const
330 : {
331 : return *m_elemIter;
332 : }
333 :
334 : template <class TElem>
335 : template <class TGeomObj>
336 : bool SurfaceView::ConstSurfaceViewElementIterator<TElem>::
337 : is_contained(TGeomObj* obj) const
338 : {
339 : #ifdef UG_PARALLEL
340 : if(m_pSurfView->is_ghost(obj)){
341 : if(m_gl.ghosts() && (m_lvl == m_topLvl)) return true;
342 : else return false;
343 : }
344 : #endif
345 :
346 0 : SurfaceState oss = m_pSurfView->surface_state(obj);
347 :
348 : if( m_validStates.contains(TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE)
349 0 : && (m_lvl == m_topLvl)
350 0 : && oss.partially_contains(MG_SHADOW))
351 : {
352 : oss = MG_SURFACE_PURE;
353 : }
354 :
355 : return m_validStates.contains(oss);
356 : }
357 :
358 : ////////////////////////////////////////////////////////////////////////////////
359 : // grid level iterators
360 : ////////////////////////////////////////////////////////////////////////////////
361 :
362 : template <class TElem>
363 : typename SurfaceView::traits<TElem>::iterator SurfaceView::
364 : begin(int si, const GridLevel& gl, SurfaceState validStates)
365 : {
366 : UG_ASSERT(si >= 0 && si < m_spMGSH->num_subsets(), "Invalid subset: "<<si);
367 0 : return typename traits<TElem>::iterator(true, this, gl, validStates, si);
368 : }
369 :
370 : template <class TElem>
371 : typename SurfaceView::traits<TElem>::iterator SurfaceView::
372 : end(int si, const GridLevel& gl, SurfaceState validStates)
373 : {
374 : UG_ASSERT(si >= 0 && si < m_spMGSH->num_subsets(), "Invalid subset: "<<si);
375 0 : return typename traits<TElem>::iterator(false, this, gl, validStates, si);
376 : }
377 :
378 : template <class TElem>
379 : typename SurfaceView::traits<TElem>::const_iterator SurfaceView::
380 : begin(int si, const GridLevel& gl, SurfaceState validStates) const
381 : {
382 : UG_ASSERT(si >= 0 && si < m_spMGSH->num_subsets(), "Invalid subset: "<<si);
383 0 : return typename traits<TElem>::const_iterator(true, this, gl, validStates, si);
384 : }
385 :
386 : template <class TElem>
387 : typename SurfaceView::traits<TElem>::const_iterator SurfaceView::
388 : end(int si, const GridLevel& gl, SurfaceState validStates) const
389 : {
390 : UG_ASSERT(si >= 0 && si < m_spMGSH->num_subsets(), "Invalid subset: "<<si);
391 0 : return typename traits<TElem>::const_iterator(false, this, gl, validStates, si);
392 : }
393 :
394 : template <class TElem>
395 : typename SurfaceView::traits<TElem>::iterator SurfaceView::
396 : begin(const GridLevel& gl, SurfaceState validStates)
397 : {
398 0 : return typename traits<TElem>::iterator(true, this, gl, validStates);
399 : }
400 :
401 : template <class TElem>
402 : typename SurfaceView::traits<TElem>::iterator SurfaceView::
403 : end(const GridLevel& gl, SurfaceState validStates)
404 : {
405 0 : return typename traits<TElem>::iterator(false, this, gl, validStates);
406 : }
407 :
408 : template <class TElem>
409 : typename SurfaceView::traits<TElem>::const_iterator SurfaceView::
410 : begin(const GridLevel& gl, SurfaceState validStates) const
411 : {
412 0 : return typename traits<TElem>::const_iterator(true, this, gl, validStates);
413 : }
414 :
415 : template <class TElem>
416 : typename SurfaceView::traits<TElem>::const_iterator SurfaceView::
417 : end(const GridLevel& gl, SurfaceState validStates) const
418 : {
419 0 : return typename traits<TElem>::const_iterator(false, this, gl, validStates);
420 : }
421 :
422 : ////////////////////////////////////////////////////////////////////////////////
423 : // implementation of SurfaceView
424 : ////////////////////////////////////////////////////////////////////////////////
425 :
426 : SmartPtr<MGSubsetHandler> SurfaceView::subset_handler()
427 : {
428 : return m_spMGSH;
429 : }
430 :
431 0 : ConstSmartPtr<MGSubsetHandler> SurfaceView::subset_handler() const
432 : {
433 0 : return m_spMGSH;
434 : }
435 :
436 : bool SurfaceView::is_adaptive() const
437 : {
438 0 : return m_adaptiveMG;
439 : }
440 :
441 : template <class TGeomObj>
442 0 : bool SurfaceView::is_contained(TGeomObj* obj, const GridLevel& gl,
443 : SurfaceState validStates) const
444 : {
445 0 : const int lvl = m_pMG->get_level(obj);
446 0 : const int topLvl = (gl.top() ? (subset_handler()->num_levels()-1) : gl.level());
447 0 : if(lvl > topLvl) return false;
448 :
449 : #ifdef UG_PARALLEL
450 : if(is_ghost(obj)){
451 : if(gl.ghosts() && (lvl == topLvl)) return true;
452 : else return false;
453 : }
454 : #endif
455 :
456 : SurfaceState oss = surface_state(obj);
457 :
458 : if( validStates.contains(TREAT_TOP_LVL_SHADOWS_AS_SURFACE_PURE)
459 0 : && (lvl == topLvl)
460 0 : && oss.partially_contains(MG_SHADOW))
461 : {
462 : oss = MG_SURFACE_PURE;
463 : }
464 :
465 0 : return validStates.contains(oss);
466 : }
467 :
468 : template <class TGeomObj>
469 0 : SurfaceView::SurfaceState SurfaceView::surface_state(TGeomObj* obj, const GridLevel& gl) const
470 : {
471 0 : const int lvl = m_pMG->get_level(obj);
472 0 : const int topLvl = (gl.top() ? (subset_handler()->num_levels()-1) : gl.level());
473 0 : if(lvl > topLvl)
474 0 : UG_THROW("SurfaceView::surface_state: Call only on objects contained "
475 : "in the grid level. (Else result is undefined)");
476 :
477 : #ifdef UG_PARALLEL
478 : if(is_ghost(obj)){
479 : if(gl.ghosts() && (lvl == topLvl)) return MG_SURFACE_PURE;
480 : else {
481 : UG_THROW("SurfaceView::surface_state: Call only on objects contained "
482 : "in the grid level. (Else result is undefined)");
483 : }
484 : }
485 : #endif
486 :
487 : SurfaceState oss = surface_state(obj);
488 :
489 : if( (lvl == topLvl)
490 0 : && oss.partially_contains(MG_SHADOW))
491 : {
492 : oss = MG_SURFACE_PURE;
493 : }
494 :
495 0 : return oss;
496 : }
497 :
498 : template <class TGeomObj>
499 : bool SurfaceView::is_ghost(TGeomObj* obj) const
500 : {
501 : #ifdef UG_PARALLEL
502 : return m_distGridMgr->is_ghost(obj);
503 : #else
504 : return false;
505 : #endif
506 : }
507 :
508 : template <class TGeomObj>
509 : bool SurfaceView::is_shadowed(TGeomObj* obj) const
510 : {
511 : return surface_state(obj).partially_contains(MG_SHADOW_RIM);
512 : }
513 :
514 : template <class TGeomObj>
515 : bool SurfaceView::is_shadowing(TGeomObj* obj) const
516 : {
517 : return surface_state(obj).contains(MG_SURFACE_RIM);
518 : }
519 :
520 : template <class TElem>
521 : bool SurfaceView::is_vmaster(TElem* elem) const
522 : {
523 : #ifdef UG_PARALLEL
524 : return m_distGridMgr->contains_status(elem, ES_V_MASTER);
525 : #else
526 : return false;
527 : #endif
528 : }
529 :
530 : template <typename TElem, typename TBaseElem>
531 0 : void SurfaceView::
532 : collect_associated(std::vector<TBaseElem*>& vAssElem,
533 : TElem* elem,
534 : const GridLevel& gl,
535 : bool clearContainer) const
536 : {
537 0 : if(clearContainer) vAssElem.clear();
538 :
539 : // collect associated on this level
540 0 : if(is_contained(elem, gl, SURFACE)){
541 : std::vector<TBaseElem*> vCoarseElem;
542 0 : CollectAssociated(vCoarseElem, *m_pMG, elem, true);
543 0 : for(size_t i = 0; i < vCoarseElem.size(); ++i)
544 : {
545 0 : if(!is_contained(vCoarseElem[i], gl, ALL)) continue;
546 0 : vAssElem.push_back(vCoarseElem[i]);
547 : }
548 0 : }
549 :
550 : // if at border of a level grid, there may be connections of the "shadow" element
551 : // to surface elements on the coarser level. These must be taken into account.
552 0 : if(is_contained(elem, gl, SURFACE_RIM))
553 : {
554 : // get parent if copy
555 0 : GridObject* pParent = m_pMG->get_parent(elem);
556 0 : TElem* parent = dynamic_cast<TElem*>(pParent);
557 0 : if(parent == NULL) return;
558 0 : if(m_pMG->num_children<TBaseElem>(parent) != 1) return;
559 :
560 : // Get connected elements
561 : std::vector<TBaseElem*> vCoarseElem;
562 0 : CollectAssociated(vCoarseElem, *m_pMG, parent, true);
563 :
564 0 : for(size_t i = 0; i < vCoarseElem.size(); ++i)
565 : {
566 0 : if(!is_contained(vCoarseElem[i], gl, SURFACE)) continue;
567 0 : vAssElem.push_back(vCoarseElem[i]);
568 : }
569 0 : }
570 :
571 : // alternative implementation taking into account possible SHADOW_RIM_COPY elem.
572 : #if 0
573 : // collect associated on this level
574 : if (is_contained(elem, gl, ALL))
575 : {
576 : std::vector<TBaseElem*> vCoarseElem;
577 : CollectAssociated(vCoarseElem, *m_pMG, elem, true);
578 : for (size_t i = 0; i < vCoarseElem.size(); ++i)
579 : if (is_contained(vCoarseElem[i], gl, ALL))
580 : vAssElem.push_back(vCoarseElem[i]);
581 : }
582 :
583 : // if at border of a grid level, there may be connections of a "shadow-rim-copy" element
584 : // to surface elements on the finer level. These must be taken into account.
585 : if (is_contained(elem, gl, SHADOW_RIM_COPY))
586 : {
587 : if (m_pMG->num_children<TElem>(elem) > 0)
588 : {
589 : TElem* child = m_pMG->get_child<TElem>(elem, 0);
590 : if (is_contained(child, gl, SURFACE_RIM))
591 : {
592 : // get connected elements
593 : std::vector<TBaseElem*> vFineElem;
594 : CollectAssociated(vFineElem, *m_pMG, child, true);
595 : for (size_t i = 0; i < vFineElem.size(); ++i)
596 : if (is_contained(vFineElem[i], gl, ALL))
597 : vAssElem.push_back(vFineElem[i]);
598 : }
599 : }
600 : }
601 : #endif
602 : }
603 :
604 :
605 : }// end of namespace
606 :
607 : #endif
|