Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
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 <algorithm>
34 : #include <cstring>
35 :
36 : #include "subset_group.h"
37 : #include "common/common.h"
38 : #include "common/util/string_util.h"
39 : #include "lib_grid/algorithms/subset_dim_util.h"
40 :
41 : using namespace std;
42 :
43 : namespace ug{
44 :
45 0 : SubsetGroup::SubsetGroup() : m_pSH(NULL) {clear();}
46 0 : SubsetGroup::SubsetGroup(ConstSmartPtr<ISubsetHandler> sh) : m_pSH(sh) {clear();}
47 :
48 0 : SubsetGroup::SubsetGroup(ConstSmartPtr<ISubsetHandler> sh, const char* names) : m_pSH(sh)
49 : {
50 0 : add(names);
51 0 : }
52 :
53 0 : SubsetGroup::SubsetGroup(ConstSmartPtr<ISubsetHandler> sh, const std::string& names) : m_pSH(sh)
54 : {
55 0 : add(names);
56 0 : }
57 :
58 0 : SubsetGroup::SubsetGroup(ConstSmartPtr<ISubsetHandler> sh, const std::vector<std::string>& vName) : m_pSH(sh)
59 : {
60 0 : add(vName);
61 0 : }
62 :
63 :
64 0 : void SubsetGroup::add(int si)
65 : {
66 0 : if(!is_init())
67 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
68 :
69 0 : if(si < 0)
70 0 : UG_THROW("Subset indices must be non-negative, but " << si);
71 :
72 : vector<int>::iterator iter;
73 0 : iter = find(m_vSubset.begin(), m_vSubset.end(), si);
74 0 : if(iter != m_vSubset.end()) return;
75 :
76 0 : m_vSubset.push_back(si);
77 0 : sort(m_vSubset.begin(), m_vSubset.end());
78 : }
79 :
80 0 : void SubsetGroup::add(const string& name)
81 : {
82 0 : string tName = TrimString(name);
83 :
84 0 : if(!is_init())
85 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
86 :
87 : size_t found = 0;
88 :
89 : // Search for name in Subset list
90 0 : for(int si = 0; si < m_pSH->num_subsets(); ++si)
91 : {
92 0 : if(strcmp (tName.c_str(), m_pSH->get_subset_name(si)) == 0)
93 : {
94 0 : found++;
95 0 : add(si);
96 : }
97 : }
98 :
99 : // if not found, return false
100 0 : if(found == 0)
101 0 : UG_THROW("SubsetGroup: No subset '"<<tName<<"' in SubsetHandler.");
102 0 : }
103 :
104 :
105 0 : void SubsetGroup::add(const char* name)
106 : {
107 0 : add(string(name));
108 0 : }
109 :
110 0 : void SubsetGroup::add(const vector<string>& vName)
111 : {
112 0 : for (size_t i = 0; i < vName.size(); ++i) {
113 0 : add(vName[i].c_str());
114 : }
115 0 : }
116 :
117 0 : void SubsetGroup::add(const SubsetGroup& ssGroup)
118 : {
119 0 : if(!is_init())
120 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
121 :
122 : // check that underlying subset handlers are equal
123 0 : if(m_pSH.get() != ssGroup.subset_handler().get())
124 0 : UG_THROW("Underlying subset handler does not match. Cannot add"
125 : " subsets to subset group.");
126 :
127 : // add all subsets
128 0 : for(size_t i = 0; i < ssGroup.size(); ++i)
129 0 : add(ssGroup[i]);
130 0 : }
131 :
132 :
133 0 : void SubsetGroup::add_all()
134 : {
135 0 : if(!is_init())
136 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
137 :
138 0 : for(int si = 0; si < m_pSH->num_subsets(); ++si)
139 0 : add(si);
140 0 : }
141 :
142 0 : void SubsetGroup::remove(int si)
143 : {
144 0 : if(!is_init())
145 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
146 :
147 0 : if(si < 0)
148 0 : UG_THROW("Subset indices must be non-negative, but "<<si);
149 :
150 : vector<int>::iterator iter;
151 0 : iter = find(m_vSubset.begin(), m_vSubset.end(), si);
152 0 : if(iter == m_vSubset.end())
153 0 : UG_THROW("Index not contained in SubsetGroup.");
154 :
155 0 : m_vSubset.erase(iter);
156 0 : }
157 :
158 0 : void SubsetGroup::remove(const string& name)
159 : {
160 0 : string tName = TrimString(name);
161 :
162 0 : if(!is_init())
163 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
164 :
165 : size_t found = 0;
166 :
167 : // Search for name in Subset list
168 0 : for(int si = 0; si < m_pSH->num_subsets(); ++si)
169 : {
170 0 : if(strcmp (tName.c_str(), m_pSH->get_subset_name(si)) == 0)
171 : {
172 0 : found++;
173 0 : remove(si);
174 : }
175 : }
176 :
177 : // if not found, return false
178 0 : if(found == 0)
179 0 : UG_THROW("SubsetGroup: No subset '"<<tName<<"' in SubsetHandler.");
180 0 : }
181 :
182 0 : void SubsetGroup::remove(const char* name)
183 : {
184 0 : remove(string(name));
185 0 : }
186 :
187 0 : void SubsetGroup::remove(const vector<string>& vName)
188 : {
189 0 : for (size_t i = 0; i < vName.size(); ++i) {
190 0 : remove(vName[i].c_str());
191 : }
192 0 : }
193 :
194 0 : void SubsetGroup::remove(const SubsetGroup& ssGroup)
195 : {
196 0 : if(!is_init())
197 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
198 :
199 : // check that underlying subset handlers are equal
200 0 : if(m_pSH.get() != ssGroup.subset_handler().get())
201 0 : UG_THROW("Underlying subset handler does not match. Cannot add"
202 : " subsets to subset group.\n");
203 :
204 : // add all subsets
205 0 : for(size_t i = 0; i < ssGroup.size(); ++i)
206 0 : remove(ssGroup[i]);
207 0 : }
208 :
209 :
210 : /// name of subset
211 0 : const char* SubsetGroup::name(size_t i) const
212 : {
213 0 : if(!is_init())
214 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
215 :
216 : // Check, that subset exist
217 0 : if(i >= size())
218 0 : UG_THROW("SubsetGroup does not contain a subset "<<i<<".");
219 :
220 0 : return m_pSH->get_subset_name(m_vSubset[i]);
221 : }
222 :
223 : /// returns if a subset is a regular grid
224 0 : bool SubsetGroup::regular_grid(size_t i) const
225 : {
226 0 : if(!is_init())
227 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
228 :
229 : // Check, that subset exist
230 0 : if(i >= size())
231 0 : UG_THROW("SubsetGroup does not contain a subset "<<i<<".");
232 :
233 0 : return SubsetIsRegularGrid(*m_pSH, m_vSubset[i]);
234 : }
235 :
236 :
237 0 : int SubsetGroup::dim(size_t i) const
238 : {
239 0 : if(!is_init())
240 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
241 :
242 : // Check, that subset exist
243 0 : if(i >= size())
244 0 : UG_THROW("SubsetGroup does not contain a subset "<<i<<".");
245 :
246 0 : return DimensionOfSubset(*m_pSH, m_vSubset[i]);
247 : }
248 :
249 0 : int SubsetGroup::get_highest_subset_dimension() const
250 : {
251 0 : if(!is_init())
252 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
253 :
254 : // without subsets no dimension
255 0 : if(size() == 0) return -1;
256 :
257 : // get first dimension
258 0 : int d = dim(0);
259 :
260 : // loop other dimensions and compare
261 0 : for(size_t i = 0; i < size(); ++i)
262 : {
263 0 : int test_dim = dim(i);
264 0 : if(d < test_dim)
265 : d = test_dim;
266 : }
267 :
268 : // return dimension
269 : return d;
270 : }
271 :
272 0 : bool SubsetGroup::contains(int si) const
273 : {
274 0 : if(!is_init())
275 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
276 :
277 : //TODO: since we subetindices are sorted be increasing number, one could optimize the search
278 : vector<int>::const_iterator iter;
279 0 : iter = find(m_vSubset.begin(), m_vSubset.end(), si);
280 0 : if(iter == m_vSubset.end()) return false;
281 : return true;
282 : }
283 :
284 0 : bool SubsetGroup::contains(const char* name) const
285 : {
286 0 : if(!is_init())
287 0 : UG_THROW("Cannot use SubsetGroup without SubsetHandler.");
288 :
289 : // Search for name in Subset list
290 0 : for(int si = 0; si < m_pSH->num_subsets(); ++si)
291 : {
292 0 : if(strcmp (name, m_pSH->get_subset_name(si)) == 0)
293 : return true;
294 : }
295 :
296 : return false;
297 : }
298 :
299 0 : bool SameDimensionsInAllSubsets(const SubsetGroup& subsetGroup)
300 : {
301 : // compute maximum
302 0 : int max = numeric_limits<int>::min();
303 0 : for(size_t s = 0; s < subsetGroup.size(); ++s)
304 0 : max = std::max(subsetGroup.dim(s), max);
305 :
306 : // check
307 0 : for(size_t s = 0; s < subsetGroup.size(); ++s)
308 0 : if(subsetGroup.dim(s) < max)
309 : return false;
310 :
311 : // same dimension in all subsets
312 : return true;
313 : }
314 :
315 0 : void RemoveLowerDimSubsets(SubsetGroup& subsetGroup)
316 : {
317 : // compute maximum
318 0 : int max = numeric_limits<int>::min();
319 0 : for(size_t s = 0; s < subsetGroup.size(); ++s)
320 0 : max = std::max(subsetGroup.dim(s), max);
321 :
322 : // check
323 : size_t s = 0;
324 0 : while(s < subsetGroup.size())
325 : {
326 0 : if(subsetGroup.dim(s) < max)
327 : {
328 : // remove and start again
329 0 : subsetGroup.remove(subsetGroup[s]);
330 : s = 0;
331 : }
332 : else
333 : {
334 : // next
335 0 : ++s;
336 : }
337 : }
338 0 : }
339 :
340 : } // end namespace ug
|