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 : ////////////////////////////////////////////////////////////////////////
34 : ////////////////////////////////////////////////////////////////////////
35 : // ...
36 : ////////////////////////////////////////////////////////////////////////
37 :
38 : #ifndef __H__LIBGRID__SELECTOR_MULTI_GRID_IMPL__
39 : #define __H__LIBGRID__SELECTOR_MULTI_GRID_IMPL__
40 :
41 : #include <cassert>
42 :
43 : namespace ug
44 : {
45 :
46 : template <class TElem>
47 : inline int
48 : MGSelector::get_section_index() const
49 : {
50 : return geometry_traits<TElem>::CONTAINER_SECTION;
51 : }
52 :
53 : inline void
54 : MGSelector::level_required(int level)
55 : {
56 : // create new SectionContainers and push them to the list,
57 : // until there are enough of them.
58 0 : while((int)m_levels.size() <= level){
59 0 : add_level();
60 : }
61 : }
62 :
63 : template <class TElem>
64 : inline void
65 0 : MGSelector::clear(int level)
66 : {
67 0 : if(m_pGrid){
68 : // mark all elements as deselected
69 : typename geometry_traits<TElem>::iterator iter;
70 0 : for(iter = begin<TElem>(level); iter != end<TElem>(level); ++iter)
71 : mark_deselected(*iter);
72 :
73 : // clear the section
74 : const int sInd = get_section_index<TElem>();
75 : if(sInd < 0)
76 0 : section_container<TElem>(level).clear();
77 : else
78 : section_container<TElem>(level).clear_section(sInd);
79 : }
80 0 : }
81 :
82 : template <class TElem>
83 : inline void
84 0 : MGSelector::clear()
85 : {
86 0 : if(m_pGrid){
87 0 : for(size_t i = 0; i < num_levels(); ++i)
88 0 : clear<TElem>(i);
89 : }
90 0 : }
91 :
92 : template <class TElem>
93 : inline size_t
94 : MGSelector::num(int level) const
95 : {
96 : const int sInd = get_section_index<TElem>();
97 0 : if(level < (int)num_levels()){
98 : if(sInd < 0)
99 0 : return section_container<TElem>(level).num_elements();
100 : else
101 0 : return section_container<TElem>(level).num_elements(sInd);
102 : }
103 : return 0;
104 : }
105 :
106 : inline size_t
107 : MGSelector::num(int level) const
108 : {
109 : return num<Vertex>(level) + num<Edge>(level)
110 : + num<Face>(level) + num<Volume>(level);
111 : }
112 :
113 : template <class TElem>
114 : inline size_t
115 0 : MGSelector::num() const
116 : {
117 : size_t n = 0;
118 0 : for(size_t i = 0; i < num_levels(); ++i)
119 0 : n += num<TElem>((int)i);
120 0 : return n;
121 : }
122 :
123 : inline size_t
124 : MGSelector::num() const
125 : {
126 : return num<Vertex>() + num<Edge>()
127 : + num<Face>() + num<Volume>();
128 : }
129 :
130 : // empty
131 : inline bool
132 : MGSelector::empty(int level) const
133 : {
134 : return num(level) == 0;
135 : }
136 :
137 : template <class TElem>
138 : inline bool
139 : MGSelector::empty(int level) const
140 : {
141 : return num<TElem>(level) == 0;
142 : }
143 :
144 : inline bool
145 : MGSelector::empty() const
146 : {
147 : return num() == 0;
148 : }
149 :
150 : template <class TElem>
151 : inline bool
152 : MGSelector::empty() const
153 : {
154 : return num<TElem>() == 0;
155 : }
156 :
157 : // begin
158 : template <class TElem>
159 : inline typename MGSelector::traits<TElem>::iterator
160 0 : MGSelector::begin()
161 : {
162 : // get the begin iterator of the first level which is not empty.
163 : // if all levels are empty the returned iterator is equal to the end iterator
164 : // of the top-level.
165 : size_t lvl = 0;
166 0 : while(empty<TElem>(lvl) && (lvl < top_level()))
167 0 : ++lvl;
168 :
169 0 : return typename MGSelector::traits<TElem>::iterator(this, lvl, begin<TElem>(lvl));
170 : }
171 :
172 : template <class TElem>
173 : inline typename MGSelector::traits<TElem>::const_iterator
174 : MGSelector::begin() const
175 : {
176 : // get the begin iterator of the first level which is not empty.
177 : // if all levels are empty the returned iterator is equal to the end iterator
178 : // of the top-level.
179 : size_t lvl = 0;
180 : while(empty<TElem>(lvl) && (lvl < top_level()))
181 : ++lvl;
182 :
183 : return typename MGSelector::traits<TElem>::const_iterator(this, lvl, begin<TElem>(lvl));
184 : }
185 :
186 : template <class TElem>
187 : inline typename MGSelector::traits<TElem>::level_iterator
188 0 : MGSelector::begin(int level)
189 : {
190 : const int sInd = get_section_index<TElem>();
191 :
192 : if(sInd < 0)
193 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
194 : section_container<TElem>(level).begin());
195 : else
196 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
197 : section_container<TElem>(level).section_begin(sInd));
198 : }
199 :
200 : template <class TElem>
201 : inline typename MGSelector::traits<TElem>::const_level_iterator
202 : MGSelector::begin(int level) const
203 : {
204 : const int sInd = get_section_index<TElem>();
205 :
206 : if(sInd < 0)
207 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
208 : section_container<TElem>(level).begin());
209 : else
210 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
211 : section_container<TElem>(level).section_begin(sInd));
212 : }
213 :
214 :
215 : template <class TElem>
216 : inline typename MGSelector::traits<TElem>::iterator
217 0 : MGSelector::end()
218 : {
219 : size_t l = top_level();
220 0 : return typename MGSelector::traits<TElem>::iterator(this, l, end<TElem>(l));
221 : }
222 :
223 : template <class TElem>
224 : inline typename MGSelector::traits<TElem>::const_iterator
225 : MGSelector::end() const
226 : {
227 : size_t l = top_level();
228 : return typename MGSelector::traits<TElem>::const_iterator(this, l, end<TElem>(l));
229 : }
230 :
231 : template <class TElem>
232 : inline typename MGSelector::traits<TElem>::level_iterator
233 0 : MGSelector::end(int level)
234 : {
235 : const int sInd = get_section_index<TElem>();
236 :
237 : if(sInd < 0)
238 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
239 : section_container<TElem>(level).end());
240 : else
241 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
242 : section_container<TElem>(level).section_end(sInd));
243 : }
244 :
245 : template <class TElem>
246 : inline typename MGSelector::traits<TElem>::const_level_iterator
247 : MGSelector::end(int level) const
248 : {
249 : const int sInd = get_section_index<TElem>();
250 :
251 : if(sInd < 0)
252 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
253 : section_container<TElem>(level).end());
254 : else
255 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
256 : section_container<TElem>(level).section_end(sInd));
257 : }
258 :
259 : template <class TElem>
260 : TElem*
261 : MGSelector::front(int level)
262 : {
263 : const int sInd = get_section_index<TElem>();
264 : return static_cast<TElem*>(section_container<TElem>(level).front(sInd));
265 : }
266 :
267 : template <class TElem>
268 : TElem*
269 : MGSelector::back(int level)
270 : {
271 : const int sInd = get_section_index<TElem>();
272 : return static_cast<TElem*>(section_container<TElem>(level).back(sInd));
273 : }
274 :
275 : template <class TElem>
276 : typename Grid::traits<TElem>::SectionContainer&
277 : MGSelector::
278 : section_container(int level)
279 : {
280 : assert(level >= 0 && "bad level index.");
281 : level_required(level);
282 0 : Level* lev = m_levels[level];
283 : return SectionContainerSelector<typename geometry_traits<TElem>::grid_base_object>::
284 0 : section_container(lev->m_vertices, lev->m_edges, lev->m_faces, lev->m_volumes);
285 : }
286 :
287 :
288 : template <class TElem>
289 : const typename Grid::traits<TElem>::SectionContainer&
290 : MGSelector::
291 : section_container(int level) const
292 : {
293 : assert((level >= 0) && (level < (int)m_levels.size()) && "bad level index.");
294 0 : const Level* lev = m_levels[level];
295 : return SectionContainerSelector<typename geometry_traits<TElem>::grid_base_object>::
296 : section_container(lev->m_vertices, lev->m_edges, lev->m_faces, lev->m_volumes);
297 : }
298 :
299 : }// end of namespace
300 :
301 : #endif
|