Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
periodic_boundary_manager_impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3 * Author: Martin Scherer
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 PERIODIC_IDENTIFIER_IMPL_HPP_
34#define PERIODIC_IDENTIFIER_IMPL_HPP_
35
36// include declarations
40#include "common/assert.h"
41#include "common/error.h"
42#include "pcl/pcl_base.h"
43
44#include <boost/mpl/map.hpp>
45#include <boost/mpl/at.hpp>
46
47#include <algorithm>
48
49namespace ug {
50
51template <class TAAPos>
52template <class TElem>
53bool ParallelShiftIdentifier<TAAPos>::match_impl(TElem* e1, TElem* e2) const {
54 if (e1 == e2)
55 return false;
56
57 AttachmentType c1 = CalculateCenter(e1, m_aaPos),
58 c2 = CalculateCenter(e2, m_aaPos), diff, error;
59 bool result = false;
60
61 VecSubtract(diff, c1, c2);
62 VecSubtract(error, diff, m_shift);
63 number len = VecLengthSq(error);
64 if (std::abs(len) < 10E-8)
65 result = true;
66 else // check for opposite shift
67 {
68 VecSubtract(error, diff, m_shift_opposite);
69 len = VecLengthSq(error);
70 if (std::abs(len) < 10E-8)
71 result = true;
72 }
73
74 return result;
75}
76
77template <class TElem>
78void PeriodicBoundaryManager::identify(TElem* e1, TElem* e2,
79 IIdentifier& ident) {
80 typedef typename
82
83 // determine masters
84 TElem* m1 = master(e1);
85 TElem* m2 = master(e2);
86
87 if (m1 || m2) {
88 // if m1 == m2, there's nothing to do
89 if (m1 != m2) {
90 if (!m1) { // m2 is master
91 make_slave(group(m2), e1);
92 } else if (!m2) { // m1 is master
93 make_slave(group(m1), e2);
94 } else if (m1 && m2) { // both are distinct masters
95 merge_groups(group(m1), group(m2));
96 } else {
97 UG_THROW("should never get here")
98 }
99 }
100 } else {
101 // create new group with e1 as master
102 Group<TElem>* g = new Group<TElem>(e1);
103 // set group of master
104 set_group(g, e1);
105 // make e2 slave
106 make_slave(g, e2);
107 }
108
109 // while elements have sides, recursively identify sub type elements
110 if (TElem::HAS_SIDES) {
111 container sides1, sides2;
112 // collect sides and identify them
113 m_pGrid->associated_elements<TElem>(sides1, e1);
114 m_pGrid->associated_elements<TElem>(sides2, e2);
115 for (size_t i = 0; i < sides1.size(); ++i) {
116 for (size_t j = 0; j < sides2.size(); ++j) {
117 if(ident.match(sides1[i], sides2[j])) {
118 identify(sides1[i], sides2[j], ident);
119 }
120 }
121 }
122 }
123}
124
125// is considered periodic if it is a master or a slave
126template <class TElem>
128 if(e)
129 return get_periodic_status_accessor<TElem>()[e] != P_NOT_PERIODIC;
130 else
131 UG_THROW("null pointer is never periodic.");
132}
133
134// gets master of e, may be null
135template <class TElem>
136TElem* PeriodicBoundaryManager::master(TElem* e) const {
137 if (group(e)) {
138 return group(e)->m_master;
139 }
140 return NULL;
141}
142
143// gets slaves of e
144template <class TElem>
147 if (group(e)) {
148 return &group(e)->get_slaves();
149 }
150 return NULL;
151}
152
153template <class TElem>
156 typedef typename Group<TElem>::SlaveIterator SlaveIter;
157
158 for (Iterator elem = m_pGrid->begin<TElem>(); elem != m_pGrid->end<TElem>();
159 ++elem) {
160 // log masters and their slaves
161 if (!(master(*elem) == *elem))
162 continue;
163
164 Group<TElem>* g = group(*elem);
165 UG_ASSERT(g, "group not valid")
166 UG_LOG("group of " << (*elem)->reference_object_id() << "\tlevel: " <<
167 m_pGrid->get_level(*elem) << "\tmaster: " <<
168 GetGridObjectCenter(*m_pGrid, g->m_master) << "\tslaves: ");
169 for (SlaveIter slave = g->get_slaves().begin();
170 slave != g->get_slaves().end(); ++slave) {
171 TElem* e = *slave;
174 "wrong level in group")
175 }
176 UG_LOG(std::endl)
177 }
178}
179
186template <class TElem>
187void PeriodicBoundaryManager::replace_parent(TElem* e, TElem* pParent) {
188
189 if (is_master(pParent)) {
190 // if parent is master, set newly created item as new master
191 Group<TElem>* g = group(pParent);
192 g->m_master = e;
193 set_group(g, e);
194 } else if(is_slave(pParent)) { // slave
195 // iterate over parent-groups slave list and replace pointer to parent
196 typename Group<TElem>::SlaveContainer* slaveCon = slaves(pParent);
197 for(typename Group<TElem>::SlaveContainer::iterator i = slaveCon->begin();
198 i != slaveCon->end(); ++i)
199 {
200 if(*i == pParent)
201 *i = e;
202 }
203 set_group(group(pParent), e);
204 }
205}
206
207template <class TElem, class TParent>
208void PeriodicBoundaryManager::handle_creation(TElem* e, TParent* pParent) {
209
210 typedef typename Group<TParent>::SlaveContainer ParentSlaveContainer;
211
212 if (!pParent)
213 return;
214
215 if (!is_periodic(pParent))
216 return;
217
219 "PeriodicBoundaryManager has to operate on a grid. No grid assigned.");
220 MultiGrid& mg = *m_pGrid;
221
222 mg.begin_marking();
223 if(TElem::BASE_OBJECT_ID != VERTEX){
225 mg.associated_elements(vrts, e);
226 for(size_t i = 0; i < vrts.size(); ++i){
227 Group<Vertex>* grp = group(vrts[i]);
228 if(!grp)
229 continue;
230 mg.mark(grp->m_master);
231 mg.mark(grp->get_slaves().begin(), grp->get_slaves().end());
232 }
233 }
234
235 if (is_master<TParent>(pParent)) {
236 // create new group for e, with e as master
237 Group<TElem>* newGroup = new Group<TElem>(e);
238 UG_ASSERT(group(e) == NULL, "element already has a group.")
239 set_group(newGroup, e);
240
241 // iterate over slaves of parent
242 ParentSlaveContainer* parentSlaves = slaves(pParent);
243 for (typename ParentSlaveContainer::iterator i_slave =
244 parentSlaves->begin(); i_slave != parentSlaves->end();
245 ++i_slave) {
246 TParent* parentSlave = *i_slave;
247 UG_ASSERT(parentSlave, "parent slave not valid")
248
249 // iterate over all children of parentSlave and make them slaves of e
250 // only matching children of type TElem are considered.
251 // note that not all children already have to exist at this point.
252 // children which are created later on are handled by the 'else' section.
253 for (size_t i_child = 0;
254 i_child < mg.num_children<TElem>(parentSlave); ++i_child) {
255 TElem* c = mg.get_child<TElem>(parentSlave, i_child);
256 UG_ASSERT(!(e->base_object_id() == VERTEX)
257 || (mg.num_children<TElem>(parentSlave) == 1),
258 "At most one 1 vertex-child is currently allowed");
259 // We use a special case for vertices here, since the position
260 // attachment has not yet been set (this is currently done after
261 // all observers have been informed about the creation of the new
262 // vertex). Note that this is no problem for edges or faces, since
263 // associated vertices have been properly initialized at that time.
264 if((e->base_object_id() == VERTEX)) {
265 make_slave(newGroup, c);
266 } else {
268 mg.associated_elements(vrts, c);
269 bool allMarked = true;
270 for(size_t i = 0; i < vrts.size(); ++i){
271 if(!mg.is_marked(vrts[i])){
272 allMarked = false;
273 break;
274 }
275 }
276
277 if(allMarked)
278 make_slave(newGroup, c);
279 }
280 }
281 }
282 } else {
283 // find the associated master of e by checking for a matching child
284 // in the set of children of the parents master.
285 // If no appropriate child already exists at this point, no master can
286 // be found. We simply leave the new element as it is, since it will
287 // be found as a slave when the associated master will be created later
288 // on (the 'if(is_master...)' case applies then.
289
290 // attention: parentGroup may be null
291 Group<TParent>* parentGroup = group<TParent>(pParent);
292
293 if (parentGroup == NULL) {
294 get_periodic_status_accessor<TElem>()[e] = P_SLAVE_MASTER_UNKNOWN;
295 return;
296 }
297
298 TParent* parentMaster = parentGroup->m_master;
299 bool master_found = false;
300 for (size_t i_child = 0; i_child < mg.num_children<TElem>(parentMaster);
301 ++i_child) {
302 TElem* c = mg.get_child<TElem>(parentMaster, i_child);
303 UG_ASSERT(!(e->base_object_id() == VERTEX)
304 || (mg.num_children<TElem>(parentMaster) == 1),
305 "At most one 1 vertex-child is currently allowed");
306 // We use a special case for vertices here, since the position
307 // attachment has not yet been set (this is currently done after
308 // all observers have been informed about the creation of the new
309 // vertex). Note that this is no problem for edges or faces, since
310 // associated vertices have been properly initialized at that time.
311 if((e->base_object_id() == VERTEX)) {
312 make_slave(group(c), e);
313 master_found = true;
314 break;
315 } else {
317 mg.associated_elements(vrts, c);
318 bool allMarked = true;
319 for(size_t i = 0; i < vrts.size(); ++i){
320 if(!mg.is_marked(vrts[i])){
321 allMarked = false;
322 break;
323 }
324 }
325
326 if(allMarked){
327 make_slave(group(c), e);
328 master_found = true;
329 break;
330 }
331 }
332 }
333
334 // wait until a master for e will be known
335 if (!master_found) {
336 get_periodic_status_accessor<TElem>()[e] = P_SLAVE_MASTER_UNKNOWN;
337 }
338 }
339
340 mg.end_marking();
341}
342
343template <class TElem>
345 GridObject* pParent, bool replacesParent) {
346 // we can only identify periodic elements, which have a periodic parent
347 if(!pParent)
348 return;
349
350 if(replacesParent){
351 replace_parent(e, static_cast<TElem*>(pParent));
352 }
353 else{
354 switch (pParent->base_object_id()) {
355 case VERTEX:
356 handle_creation(e, static_cast<Vertex*>(pParent));
357 break;
358 case EDGE:
359 handle_creation(e, static_cast<Edge*>(pParent));
360 break;
361 case FACE:
362 handle_creation(e, static_cast<Face*>(pParent));
363 break;
364 // ignore volumes, as these are not meant to be periodic
365 case VOLUME:
366 break;
367 default:
368 UG_THROW("no handling for parent type: " << pParent->base_object_id())
369 }
370 }
371}
372
374template <class TElem>
375void PeriodicBoundaryManager::handle_deletion(TElem* e, TElem* replacedBy) {
376 if((!is_periodic(e)) || replacedBy)
377 return;
378
379 if (is_master(e)) {
380 // delete a master completely...
381 if (replacedBy) {
382 UG_ASSERT(!group(replacedBy),
383 "replacing element is already in group")
384 make_master(group(e), replacedBy);
385 } else {
387 }
388 } else { // slave
389 UG_ASSERT(is_slave(e), "e should be a slave")
390 if(!remove_slave(e))
391 UG_THROW("old slave not removed.")
392 }
393}
394
395template <class TElem>
397 UG_ASSERT(g, "invalid group")
398 UG_ASSERT(slave, "invalid slave")
399 UG_ASSERT(group(slave) != g, "trying to add a duplicate slave!")
401 "level of slave and group mismatch")
402
403 // if slave is already engrouped, remove it first
404 if(group(slave)) {
405 UG_LOG("slave already engrouped. removing it from former group\n")
406 if(!remove_slave(slave)) {
407 UG_THROW("slave could not be removed")
408 }
409 }
410
411 // add slave to group and set group attachment/status
412 g->add_slave(slave);
413 set_group(g, slave);
414}
415
416template <class TElem>
418 // group has a master, reset its group
419 if(g->m_master) {
420 set_group<TElem>(NULL, g->m_master);
421 }
422 g->m_master = new_master;
423}
424
425template <class TElem>
427 if (slaves(e)) {
428 typename Group<TElem>::SlaveContainer& s = *slaves(e);
429 typename Group<TElem>::SlaveIterator pos = std::find(s.begin(), s.end(), e);
430 if (pos != s.end()) {
431// s.erase(pos);
432// set_group<TElem>(NULL, e);
433
434 // todo this is the only slave left, remove whole group?!
435 if(s.size() == 1) {
436 UG_LOGN("delete last slave, remove_group")
438 }
439 // todo what if e was the last slave of of group?
440// if(s.empty()) {
441// UG_THROW("empty group leftover....")
442// }
443 return true;
444 }
445 }
446 return false;
447}
448
449template <class TElem>
451 UG_ASSERT(g, "should remove invalid group")
452
453 // reset group pointers of all group members to NULL
454 set_group<TElem>(NULL, g->m_master);
456 typename Group<TElem>::SlaveIterator iter;
457 for (iter = s.begin(); iter != s.end(); ++iter) {
458 set_group<TElem>(NULL, *iter);
459 }
460
461 delete g;
462}
463
467template <class TElem>
469 UG_ASSERT(g0 && g1, "groups not valid")
470 UG_ASSERT(g0 != g1, "groups are equal")
471
472 typedef typename Group<TElem>::SlaveContainer SlaveContainer;
473 typedef typename Group<TElem>::SlaveIterator SlaveIterator;
474
475 SlaveContainer& slaves_g1 = g1->get_slaves();
476
477 // insert slaves of g1 at the end of slaves of g0
478 for (SlaveIterator iter = slaves_g1.begin(); iter != slaves_g1.end();
479 ++iter) {
480 TElem* e = *iter;
481 UG_ASSERT(e, "slave not valid")
482 UG_ASSERT(e != g0->m_master, "slave of g1 is master of g0!")
483 // we do not use make_slave() here, because g1 will be deleted at the end
484 g0->add_slave(e);
485 set_group(g0, e);
486 }
487
488 // make old master a slave of group g1
489 // we do not use make_slave() here, because g1 will be deleted at the end
490 g0->add_slave(g1->m_master);
491 set_group(g0, g1->m_master);
492
493 // remove old group
494 delete g1;
495}
496
497template <class TElem>
499 PeriodicStatus p = get_periodic_status_accessor<TElem>()[e];
500 return (p == P_SLAVE || p == P_SLAVE_MASTER_UNKNOWN);
501}
502
503template <class TElem>
505 return get_periodic_status_accessor<TElem>()[e] == P_MASTER;
506}
507
508template <class TElem>
510 TElem* e) const {
511 UG_ASSERT(e, "element not valid.")
512 return get_group_accessor<TElem>()[e];
513}
514
515template <class TElem>
517 UG_ASSERT(e, "element not valid for attachment access.")
518 // set group pointer of element e
519 get_group_accessor<TElem>()[e] = g;
520
521 // set periodic status
522 if (g == NULL) {
523 get_periodic_status_accessor<TElem>()[e] = P_NOT_PERIODIC;
524 } else {
525 if (g->m_master == e)
526 get_periodic_status_accessor<TElem>()[e] = P_MASTER;
527 else
528 get_periodic_status_accessor<TElem>()[e] = P_SLAVE;
529 }
530}
531
532template <class TElem, class TIterator>
534 TIterator begin,
535 TIterator end,
536 typename Group<TElem>::unique_pairs& s,
537 ISubsetHandler* sh) {
538
539 typedef typename Group<TElem>::SlaveContainer Container;
540 typedef typename Group<TElem>::SlaveIterator SlaveIter;
541 typedef typename ElementStorage<TElem>::SectionContainer::const_iterator SecContainerIter;
542
543 for (SecContainerIter iter = begin; iter != end; ++iter) {
544 TElem* e = *iter;
545 if(! e)
546 continue;
547 if(!is_periodic(e)) {
548 // lookup subset name of element
549 const char* sh_name = "";
550 if(sh) {
551 int element_si = sh->get_subset_index(e);
552 sh_name = sh->get_subset_name(element_si);
553 }
554 UG_THROW("Element in subset '" << sh_name
555 << "' is not periodic after identification: "
557 << "\nCheck your geometry for symmetry!\n")
558 }
559
560 if (master(e) == e) {
561 Container* _slaves = slaves(e);
562 if(! _slaves)
563 UG_THROW("masters slave storage is not valid.")
564
565 if(_slaves->empty())
566 UG_THROW("master has no slaves")
567
568 for (SlaveIter i = _slaves->begin(); i != _slaves->end(); ++i) {
569 TElem* slave = *i;
570 typename Group<TElem>::master_slave_pair p = std::make_pair(e, slave);
571 bool inserted = (s.insert(p)).second;
572 if(! inserted)
573 UG_THROW("master/slave pair already exists.");
574 }
575 }
576 }
577}
578
579template <class TDomain>
580void IdentifySubsets(TDomain& dom, const char* sName1, const char* sName2) {
581 // get subset handler from domain
582 typedef typename TDomain::subset_handler_type subset_handler_type;
583
584 subset_handler_type& sh = *dom.subset_handler();
585
586 int si1 = sh.get_subset_index(sName1);
587 int si2 = sh.get_subset_index(sName2);
588
589#ifdef UG_PARALLEL
590 //if(pcl::NumProcs() > 1)
591 // UG_THROW("sorry, in real parallel environment periodic bnds are not impled yet.");
592#endif
593
594 if (si1 == -1)
595 UG_THROW("IdentifySubsets: given subset name " << sName1 << " does not exist");
596 if (si2 == -1)
597 UG_THROW("IdentifySubsets: given subset name " << sName2 << " does not exist");
598
599 IdentifySubsets(dom, si1, si2);
600}
601
603template <class TDomain>
604void IdentifySubsets(TDomain& dom, int sInd1, int sInd2) {
605
606#ifdef UG_PARALLEL
607 //if(pcl::NumProcs() > 1)
608 // UG_THROW("sorry, in real parallel environment periodic bnds are not impled yet.");
609#endif
610
611 if (sInd1 == -1 || sInd2 == -1) {
612 UG_THROW("IdentifySubsets: at least one invalid subset given!")
613 }
614
615 if(sInd1 == sInd2) {
616 UG_THROW("IdentifySubsets: can not identify two identical subsets!")
617 }
618
619 // ensure grid has support for periodic boundaries
620 if (!dom.grid()->has_periodic_boundaries()) {
621 dom.grid()->set_periodic_boundaries(true);
622 }
623
624 PeriodicBoundaryManager& pbm = *dom.grid()->periodic_boundary_manager();
625
626 typedef typename TDomain::position_type position_type;
627 typedef typename TDomain::position_accessor_type position_accessor_type;
628
629 // get subset handler from domain
630 typedef typename TDomain::subset_handler_type subset_handler_type;
631
632 subset_handler_type& sh = *dom.subset_handler();
633
634 // get aaPos from domain
635 position_accessor_type& aaPos = dom.position_accessor();
636
637 // create parallel shift identifier to match subset elements
639
640 // shift vector between subsets
641 position_type shift;
642
643 // collect all geometric objects (even for all levels in case of multi grid)
644 GridObjectCollection goc1 = sh.get_grid_objects_in_subset(sInd1);
645 GridObjectCollection goc2 = sh.get_grid_objects_in_subset(sInd2);
646
647 if(goc1.num<Vertex>() != goc2.num<Vertex>()) {
648 UG_THROW("IdentifySubsets: Given subsets have different number of vertices."
649 "\nnum# in " << sh.get_subset_name(sInd1) << ": " << goc1.num<Vertex>() <<
650 "\nnum# in " << sh.get_subset_name(sInd2) << ": " << goc2.num<Vertex>())
651 }
652
653 if(goc1.num<Edge>() != goc2.num<Edge>()) {
654 UG_THROW("IdentifySubsets: Given subsets have different number of edges."
655 "\nnum# in " << sh.get_subset_name(sInd1) << ": " << goc1.num<Edge>() <<
656 "\nnum# in " << sh.get_subset_name(sInd2) << ": " << goc2.num<Edge>())
657 }
658
659 if(goc1.num<Face>() != goc2.num<Face>()) {
660 UG_THROW("IdentifySubsets: Given subsets have different number of faces."
661 "\nnum# in " << sh.get_subset_name(sInd1) << ": " << goc1.num<Face>() <<
662 "\nnum# in " << sh.get_subset_name(sInd2) << ": " << goc2.num<Face>())
663 }
664
665 // map start type of recursion dependent to TDomain
666 // in 3d start with faces, in 2d with edges, in 1d with vertices
667 // namespace mpl = boost::mpl;
668 // typedef mpl::map<mpl::pair<Domain1d, Vertex>,
669 // mpl::pair<Domain2d, Edge>,
670 // mpl::pair<Domain3d, Face> > m;
671
672 // typedef typename mpl::at<m, TDomain>::type TElem;
673 typedef typename grid_dim_traits<TDomain::dim>::side_type TElem;
675
676 // calculate shift vector for top level
677 position_type c1 = CalculateCenter(goc1.begin<TElem>(0), goc1.end<TElem>(0),
678 aaPos);
679 position_type c2 = CalculateCenter(goc2.begin<TElem>(0), goc2.end<TElem>(0),
680 aaPos);
681
682 VecSubtract(shift, c1, c2);
683 ident.set_shift(shift);
684
685 // for each level of multi grid. In case of simple grid only one iteration
686 for (size_t lvl = 0; lvl < goc1.num_levels(); lvl++) {
687 // identify corresponding elements for second subset. A element is considered
688 // to have symmetric element in second subset if there exists a shift vector between them.
689 // todo use kd-tree for fast lookup of shifted elements
690 for (gocIter iter1 = goc1.begin<TElem>(lvl);
691 iter1 != goc1.end<TElem>(lvl); ++iter1)
692 for (gocIter iter2 = goc2.begin<TElem>(lvl);
693 iter2 != goc2.end<TElem>(lvl); ++iter2) {
694 if(ident.match(*iter1, *iter2)) {
695 pbm.identify(*iter1, *iter2, ident);
696 }
697 }
698 }
699
700 // ensure periodic identification has been performed correctly
701 pbm.check_periodicity(goc1, goc2, &sh);
702}
703
704} // end namespace ug
705
706#endif /* PERIODIC_IDENTIFIER_IMPL_HPP_ */
parameterString p
parameterString s
Base-class for edges.
Definition grid_base_objects.h:397
Faces are 2-dimensional objects.
Definition grid_base_objects.h:510
void end_marking()
ends a marking sequence. Call this method when you're done with marking.
Definition grid.cpp:1285
bool is_marked(GridObject *obj) const
returns true if the object is marked, false if not.
Definition grid_impl.hpp:843
void mark(GridObject *obj)
marks the object. Calls are only valid between calls to Grid::begin_marking and Grid::end_marking.
Definition grid_impl.hpp:773
void begin_marking()
begin marking.
Definition grid.cpp:1262
void associated_elements(traits< Vertex >::secure_container &elemsOut, TElem *e)
Puts all elements of type TAss which are contained in 'e' or which contain 'e' into elemsOut.
Definition grid_impl.hpp:466
a helper class that holds a collection of possibly unconnected geometric-objects.
Definition grid_object_collection.h:96
geometry_traits< TGeomObj >::iterator begin(size_t level=0)
Definition grid_object_collection_impl.hpp:95
geometry_traits< TGeomObj >::iterator end(size_t level=0)
Definition grid_object_collection_impl.hpp:106
size_t num() const
Definition grid_object_collection_impl.hpp:130
size_t num_levels() const
returns the number of levels
Definition grid_object_collection.h:128
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition grid_base_objects.h:157
virtual int base_object_id() const =0
Interface to match periodic geometric elements.
Definition periodic_boundary_manager.h:48
virtual bool match(Vertex *, Vertex *)=0
Definition subset_handler_interface.h:223
const char * get_subset_name(int subsetIndex) const
returns the name of a subset
Definition subset_handler_interface.cpp:438
int get_subset_index(GridObject *elem) const
Definition subset_handler_interface.cpp:560
Definition multi_grid.h:72
int get_level(TElem *elem) const
Definition multi_grid.h:206
TChild * get_child(TElem *elem, size_t ind) const
returns the i-th child of the given child-type
Definition multi_grid.h:268
geometry_traits< TElem >::iterator begin(int level)
Definition multi_grid.h:158
geometry_traits< TElem >::iterator end(int level)
Definition multi_grid.h:168
size_t num_children(TElem *elem) const
returns the number of children of the given child-type
Definition multi_grid.h:225
This class matches geometric elements which are parallel translated.
Definition periodic_boundary_manager.h:64
TPosAA::ValueType AttachmentType
Definition periodic_boundary_manager.h:71
void set_shift(AttachmentType &shift)
Definition periodic_boundary_manager.h:73
virtual bool match(Vertex *v1, Vertex *v2)
Definition periodic_boundary_manager.h:66
bool match_impl(TElem *, TElem *) const
Definition periodic_boundary_manager_impl.hpp:53
Definition periodic_boundary_manager.h:107
TElem * m_master
Definition periodic_boundary_manager.h:123
std::set< master_slave_pair > unique_pairs
Definition periodic_boundary_manager.h:113
Container SlaveContainer
Definition periodic_boundary_manager.h:109
Container & get_slaves()
Definition periodic_boundary_manager.h:122
Container::iterator SlaveIterator
Definition periodic_boundary_manager.h:110
std::pair< TElem *, TElem * > master_slave_pair
Definition periodic_boundary_manager.h:112
void add_slave(TElem *e)
Definition periodic_boundary_manager.h:117
Definition periodic_boundary_manager.h:99
void handle_creation_cast_wrapper(TElem *e, GridObject *parent, bool replacesParent)
casts parent pointer to exact type before calling handle_creation
Definition periodic_boundary_manager_impl.hpp:344
void identify(TElem *e1, TElem *e2, IIdentifier &i)
Definition periodic_boundary_manager_impl.hpp:78
bool is_master(TElem *) const
Definition periodic_boundary_manager_impl.hpp:504
void check_elements_periodicity(TIterator begin, TIterator end, typename Group< TElem >::unique_pairs &s, ISubsetHandler *sh)
Definition periodic_boundary_manager_impl.hpp:533
void remove_group(Group< TElem > *g)
Definition periodic_boundary_manager_impl.hpp:450
bool is_periodic(TElem *e) const
Definition periodic_boundary_manager_impl.hpp:127
void make_master(Group< TElem > *g, TElem *e)
Definition periodic_boundary_manager_impl.hpp:417
Group< TElem >::SlaveContainer * slaves(TElem *e) const
Definition periodic_boundary_manager_impl.hpp:146
void handle_creation(TElem *e, TParent *pParent)
handles creation of element type
Definition periodic_boundary_manager_impl.hpp:208
void merge_groups(Group< TElem > *g0, Group< TElem > *g1)
Definition periodic_boundary_manager_impl.hpp:468
void set_group(Group< TElem > *g, TElem *e)
Definition periodic_boundary_manager_impl.hpp:516
Group< TElem > * group(TElem *e) const
Definition periodic_boundary_manager_impl.hpp:509
Grid * get_grid() const
Definition periodic_boundary_manager.cpp:96
TElem * master(TElem *e) const
Definition periodic_boundary_manager_impl.hpp:136
bool check_periodicity(const GridObjectCollection &goc1, const GridObjectCollection &goc2, ISubsetHandler *sh=NULL)
checks that all elements of given gocs are periodic (called after identification)
Definition periodic_boundary_manager.cpp:257
MultiGrid * m_pGrid
grid instance we operate on
Definition periodic_boundary_manager.h:208
bool is_slave(TElem *) const
Definition periodic_boundary_manager_impl.hpp:498
PeriodicStatus
Definition periodic_boundary_manager.h:129
@ P_SLAVE
Definition periodic_boundary_manager.h:130
@ P_NOT_PERIODIC
Definition periodic_boundary_manager.h:130
@ P_MASTER
Definition periodic_boundary_manager.h:130
@ P_SLAVE_MASTER_UNKNOWN
Definition periodic_boundary_manager.h:130
bool remove_slave(TElem *slave)
Definition periodic_boundary_manager_impl.hpp:426
void print_identification() const
Definition periodic_boundary_manager_impl.hpp:154
void make_slave(Group< TElem > *g, TElem *e)
make element e slave of group g
Definition periodic_boundary_manager_impl.hpp:396
void handle_deletion(TElem *e, TElem *replacedBy)
handles deletion of element type
Definition periodic_boundary_manager_impl.hpp:375
void replace_parent(TElem *e, TElem *pParent)
replaces all group occurrances of pParent by the specified elem
Definition periodic_boundary_manager_impl.hpp:187
Container::const_iterator const_iterator
Definition section_container.h:64
Container::iterator iterator
Definition section_container.h:63
Base-class for all vertex-types.
Definition grid_base_objects.h:231
vector3 GetGridObjectCenter(Grid &g, TElem *elem)
Returns the center of the given element (SLOW - for debugging only!)
Definition debug_util_impl.hpp:47
#define UG_ASSERT(expr, msg)
Definition assert.h:70
#define UG_THROW(msg)
Definition error.h:57
#define UG_LOG(msg)
Definition log.h:367
#define UG_LOGN(msg)
Definition log.h:369
double number
Definition types.h:124
void CalculateCenter(vector_t &centerOut, const vector_t *pointSet, size_t numPoints)
calculates the center of a point-set
Definition math_util_impl.hpp:98
void VecSubtract(vector_t &vOut, const vector_t &v1, const vector_t &v2)
subtracts v2 from v1 and stores the result in a vOut
Definition math_vector_functions_common_impl.hpp:226
vector_t::value_type VecLengthSq(const vector_t &v)
returns the squared length of v. Faster than VecLength.
Definition math_vector_functions_common_impl.hpp:324
the ug namespace
void IdentifySubsets(TDomain &dom, int sInd1, int sInd2)
identifies subset 1 with subset 2. If the grid of given domain has no periodic boundary manager attac...
Definition periodic_boundary_manager_impl.hpp:604
@ VOLUME
Definition grid_base_objects.h:63
@ VERTEX
Definition grid_base_objects.h:60
@ EDGE
Definition grid_base_objects.h:61
@ FACE
Definition grid_base_objects.h:62
PointerConstArray< TElem * > secure_container
Definition grid.h:146
Definition grid_dim_traits.h:53