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 : #ifndef __H__LIBGRID__SUBSET_HANDLER_MULTI_GRID_IMPL__
34 : #define __H__LIBGRID__SUBSET_HANDLER_MULTI_GRID_IMPL__
35 :
36 : #include <cassert>
37 :
38 : namespace ug
39 : {
40 :
41 : template <class TElem>
42 : typename geometry_traits<TElem>::iterator
43 0 : MultiGridSubsetHandler::
44 : begin(int subsetIndex, int level)
45 : {
46 : const int sectionInd = geometry_traits<TElem>::CONTAINER_SECTION;
47 :
48 : assert((subsetIndex >= 0) && (subsetIndex < (int)num_subsets_in_list()) &&
49 : "ERROR in SubsetHandler::begin(): bad subset index.");
50 :
51 : level_required(level);
52 :
53 : if(sectionInd < 0)
54 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
55 : section_container<TElem>(subsetIndex, level).begin());
56 : else
57 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
58 : section_container<TElem>(subsetIndex, level).section_begin(sectionInd));
59 : }
60 :
61 : template <class TElem>
62 : typename geometry_traits<TElem>::iterator
63 0 : MultiGridSubsetHandler::
64 : end(int subsetIndex, int level)
65 : {
66 : const int sectionInd = geometry_traits<TElem>::CONTAINER_SECTION;
67 :
68 : assert((subsetIndex >= 0) && (subsetIndex < (int)num_subsets_in_list()) &&
69 : "ERROR in SubsetHandler::end(): bad subset index.");
70 :
71 : level_required(level);
72 :
73 : if(sectionInd < 0)
74 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
75 : section_container<TElem>(subsetIndex, level).end());
76 : else
77 : return iterator_cast<typename geometry_traits<TElem>::iterator>(
78 : section_container<TElem>(subsetIndex, level).section_end(sectionInd));
79 : }
80 :
81 : template <class TElem>
82 : typename geometry_traits<TElem>::const_iterator
83 0 : MultiGridSubsetHandler::
84 : begin(int subsetIndex, int level) const
85 : {
86 : UG_ASSERT(subsetIndex >= 0, "-1 is not a valid subset index when accessing iterators!");
87 0 : if(subsetIndex >= (int)num_subsets_in_list() || level >= (int)num_levels())
88 0 : return end<TElem>(subsetIndex, level);
89 :
90 : const int sectionInd = geometry_traits<TElem>::CONTAINER_SECTION;
91 :
92 : if(sectionInd < 0)
93 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
94 : section_container<TElem>(subsetIndex, level).begin());
95 : else
96 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
97 : section_container<TElem>(subsetIndex, level).section_begin(sectionInd));
98 : }
99 :
100 : template <class TElem>
101 : typename geometry_traits<TElem>::const_iterator
102 0 : MultiGridSubsetHandler::
103 : end(int subsetIndex, int level) const
104 : {
105 : UG_ASSERT(subsetIndex >= 0, "-1 is not a valid subset index when accessing iterators!");
106 0 : if(subsetIndex >= (int)num_subsets_in_list() || level >= (int)num_levels()){
107 0 : static typename geometry_traits<TElem>::const_iterator dummyEndIter;
108 : return dummyEndIter;
109 : }
110 :
111 : const int sectionInd = geometry_traits<TElem>::CONTAINER_SECTION;
112 :
113 : if(sectionInd < 0)
114 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
115 : section_container<TElem>(subsetIndex, level).end());
116 : else
117 : return iterator_cast<typename geometry_traits<TElem>::const_iterator>(
118 : section_container<TElem>(subsetIndex, level).section_end(sectionInd));
119 : }
120 : template <class TElem>
121 : void
122 : MultiGridSubsetHandler::
123 : clear_subset_elements(int subsetIndex)
124 : {
125 : for(int i = 0; i < (int)num_levels(); ++i)
126 : clear_subset_elements<TElem>(subsetIndex, i);
127 : }
128 :
129 : template <class TElem>
130 : void MultiGridSubsetHandler::
131 : clear_subset_elements(int subsetIndex, int level)
132 : {
133 : const int sectionInd = geometry_traits<TElem>::CONTAINER_SECTION;
134 :
135 : assert((subsetIndex >= 0) && (subsetIndex < (int)num_subsets_in_list()) &&
136 : "ERROR in SubsetHandler::clear_subsets_elements(): bad subset index.");
137 :
138 : // iterate through the elements of type TElem and erase them from the subsets list.
139 : if(m_pGrid != NULL)
140 : {
141 : typename Grid::traits<TElem>::SectionContainer& secCon =
142 : section_container<TElem>(subsetIndex, level);
143 :
144 : typename geometry_traits<TElem>::iterator iter = begin<TElem>(subsetIndex, level);
145 : while(iter != end<TElem>(subsetIndex, level))
146 : {
147 : typename geometry_traits<TElem>::iterator iterErase = iter++;
148 : alter_subset_index(*iterErase) = -1;
149 : secCon.erase(iterErase, sectionInd);
150 : }
151 : }
152 : }
153 :
154 : template <class TElem>
155 : uint
156 : MultiGridSubsetHandler::
157 : num(int subsetIndex, int level) const
158 : {
159 : const int sectionInd = geometry_traits<TElem>::CONTAINER_SECTION;
160 :
161 : assert((subsetIndex >= 0) && (subsetIndex < (int)num_subsets_in_list()) &&
162 : "ERROR in SubsetHandler::num_elements(): bad subset index.");
163 :
164 : // TODO: Maybe the passed level should be of uint-type
165 : // if level does not exist, there are no elements in it
166 : if((uint)level >= num_levels()) return 0;
167 :
168 : if(sectionInd < 0)
169 : return section_container<TElem>(subsetIndex, level).num_elements();
170 : else
171 : return section_container<TElem>(subsetIndex, level).num_elements(sectionInd);
172 : }
173 :
174 : template <class TElem>
175 : uint
176 0 : MultiGridSubsetHandler::
177 : num(int subsetIndex) const
178 : {
179 : const int sectionInd = geometry_traits<TElem>::CONTAINER_SECTION;
180 :
181 : assert((subsetIndex >= 0) && (subsetIndex < (int)num_subsets_in_list()) &&
182 : "ERROR in SubsetHandler::num_elements(): bad subset index.");
183 :
184 : uint numElems = 0;
185 : if(sectionInd < 0)
186 : {
187 0 : for(size_t i = 0; i < m_levels.size(); ++i)
188 0 : numElems += section_container<TElem>(subsetIndex, (int)i).num_elements();
189 : }
190 : else
191 : {
192 0 : for(size_t i = 0; i < m_levels.size(); ++i)
193 0 : numElems += section_container<TElem>(subsetIndex, (int)i).num_elements(sectionInd);
194 : }
195 :
196 0 : return numElems;
197 : }
198 :
199 : template <class TElem>
200 : uint
201 0 : MultiGridSubsetHandler::
202 : num() const
203 : {
204 : uint n = 0;
205 0 : for(size_t i = 0; i < num_subsets_in_list(); ++i)
206 0 : n += num<TElem>(i);
207 :
208 0 : return n;
209 : }
210 :
211 : template<class TElem>
212 0 : void MultiGridSubsetHandler::
213 : change_elem_subset_indices(int indOld, int indNew)
214 : {
215 : typedef typename geometry_traits<TElem>::iterator iterator;
216 :
217 0 : for(size_t i = 0; i < m_levels.size(); ++i)
218 : {
219 0 : for(iterator iter = begin<TElem>(indOld, i);
220 0 : iter != end<TElem>(indOld, i); iter++)
221 : alter_subset_index(*iter, indNew);
222 : }
223 0 : }
224 :
225 : inline void MultiGridSubsetHandler::
226 : level_required(int level)
227 : {
228 0 : while((int)m_levels.size() <= level) add_level();
229 : }
230 :
231 0 : inline void MultiGridSubsetHandler::
232 : level_required(int level) const
233 : {
234 0 : if(level >= (int)num_levels()){
235 0 : UG_THROW("Can't create additional levels in const MGSubsetHandler. "
236 : << "num current levels: " << num_levels()
237 : << " required level: " << level);
238 : }
239 0 : }
240 :
241 : template <class TElem>
242 : typename Grid::traits<TElem>::SectionContainer&
243 : MultiGridSubsetHandler::
244 : section_container(int si, int lvl)
245 : {
246 : Subset* sub = subset(si, lvl);
247 : return SectionContainerSelector<typename geometry_traits<TElem>::grid_base_object>::
248 0 : section_container(sub->m_vertices, sub->m_edges, sub->m_faces, sub->m_volumes);
249 : }
250 :
251 :
252 : template <class TElem>
253 : const typename Grid::traits<TElem>::SectionContainer&
254 : MultiGridSubsetHandler::
255 : section_container(int si, int lvl) const
256 : {
257 : const Subset* sub = subset(si, lvl);
258 : return SectionContainerSelector<typename geometry_traits<TElem>::grid_base_object>::
259 : section_container(sub->m_vertices, sub->m_edges, sub->m_faces, sub->m_volumes);
260 : }
261 :
262 : }// end of namespace
263 :
264 : #endif
265 :
|