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 "polychain_util.h"
34 : #include "lib_grid/callbacks/callbacks.h"
35 :
36 : using namespace std;
37 :
38 : namespace ug
39 : {
40 :
41 : ////////////////////////////////////////////////////////////////////////
42 : std::pair<Vertex*, Edge*>
43 0 : GetNextSectionOfPolyChain(Grid& grid, std::pair<Vertex*, Edge*> lastSection,
44 : Grid::edge_traits::callback cbEdgeIsInPolyChain)
45 : {
46 0 : if(!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
47 : {
48 : // we have to enable this option, since nothing works without it in reasonable time.
49 : LOG("WARNING in GetFirstVertexOfPolyChain(...): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES.\n");
50 0 : grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
51 : }
52 :
53 : // get the vertex which is connected to the vertex in lastSection->frist
54 : // the edge in lastSection->second
55 0 : Vertex* nVrt = GetConnectedVertex(lastSection.second, lastSection.first);
56 :
57 : // find the next edge
58 0 : Grid::AssociatedEdgeIterator edgesEnd = grid.associated_edges_end(nVrt);
59 0 : for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(nVrt);
60 0 : iter != edgesEnd; ++iter)
61 : {
62 0 : if(cbEdgeIsInPolyChain(*iter) && (*iter != lastSection.second)){
63 : // we got the next edge
64 : return make_pair(nVrt, *iter);
65 : }
66 : }
67 : // we couldn't find another section. Return an empty one
68 0 : return std::make_pair<Vertex*, Edge*>(NULL, NULL);
69 : }
70 :
71 : ////////////////////////////////////////////////////////////////////////
72 0 : bool SplitIrregularPolyChain(SubsetHandler& sh, int srcIndex, int targetIndex)
73 : {
74 0 : if(!sh.grid())
75 0 : throw(UGError("No grid assigned to subset handler"));
76 :
77 0 : Grid& grid = *sh.grid();
78 :
79 0 : if(!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))
80 : {
81 : // we have to enable this option, since nothing works without it in reasonable time.
82 : LOG("WARNING in SplitPolyChain(...): auto-enabling VRTOPT_STORE_ASSOCIATED_EDGES.\n");
83 0 : grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
84 : }
85 :
86 : // we'll start at the first section of the polychain
87 0 : pair<Vertex*, Edge*> curSec = GetFirstSectionOfPolyChain(grid,
88 0 : sh.begin<Edge>(srcIndex),
89 0 : sh.end<Edge>(srcIndex),
90 : IsInSubset(sh, srcIndex));
91 :
92 : // Follow the polychain until either the end is reached or an irregular
93 : // vertex is encountered. Those conditions are enough.
94 :
95 :
96 0 : grid.begin_marking();
97 :
98 : size_t numEdgesEncountered = 0;
99 :
100 0 : while(curSec.first)
101 : {
102 : Vertex* curVrt = curSec.first;
103 : Edge* curEdge = curSec.second;
104 : grid.mark(curVrt);
105 : grid.mark(curEdge);
106 :
107 0 : numEdgesEncountered++;
108 :
109 : // check whether the connected vertex is marked or irregular
110 0 : Vertex* cv = GetConnectedVertex(curEdge, curVrt);
111 :
112 0 : if(grid.is_marked(cv))
113 : break;
114 :
115 : size_t counter = 0;
116 :
117 0 : Grid::AssociatedEdgeIterator edgesEnd = grid.associated_edges_end(cv);
118 0 : for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(cv);
119 0 : iter != edgesEnd; ++iter)
120 : {
121 0 : if(sh.get_subset_index(*iter) == srcIndex)
122 0 : ++counter;
123 : }
124 :
125 0 : if(counter > 2){
126 : // the vertex is irregular
127 : break;
128 : }
129 :
130 : // ok - everything's still regular
131 0 : curSec = GetNextSectionOfPolyChain(grid, curSec, IsInSubset(sh, srcIndex));
132 : }
133 :
134 : // if all edges have been encountered, we're done.
135 0 : if(numEdgesEncountered == sh.num<Edge>(srcIndex)){
136 0 : grid.end_marking();
137 0 : return false;
138 : }
139 :
140 : // some edges are left. assign them to the target subset
141 : EdgeIterator iter = sh.begin<Edge>(srcIndex);
142 0 : while(iter != sh.end<Edge>(srcIndex))
143 : {
144 : Edge* e = *iter;
145 : ++iter;
146 0 : if(!grid.is_marked(e))
147 0 : sh.assign_subset(e, targetIndex);
148 : }
149 :
150 0 : grid.end_marking();
151 :
152 : return true;
153 : }
154 :
155 : }// end of namespace
|