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 : #ifndef __H__UG__LIB_DISC__COMMON__MULTI_INDEX__
34 : #define __H__UG__LIB_DISC__COMMON__MULTI_INDEX__
35 :
36 : #include <vector>
37 : #include <iostream>
38 : #include <assert.h>
39 :
40 : #include "common/common.h"
41 : #include "lib_algebra/small_algebra/blocks.h" // needed for BlockRef
42 :
43 : namespace ug{
44 :
45 : /**
46 : * A MultiIndex is just a vector of integers.
47 : */
48 : template<int N, typename TSingleIndexType = size_t>
49 : class MultiIndex
50 : {
51 : public:
52 : typedef TSingleIndexType single_index_type;
53 :
54 : public:
55 : /// number of indices in multi index
56 : inline size_t size() const {return N;}
57 :
58 : /// access to index component
59 : inline single_index_type& operator[] (size_t i)
60 : {
61 : UG_ASSERT(i < N, "Index invalid");
62 : return m_indices[i];
63 : }
64 :
65 : /// const access to index component
66 : inline const single_index_type& operator[] (size_t i) const
67 : {
68 : UG_ASSERT(i < N, "Index invalid");
69 : return m_indices[i];
70 : }
71 :
72 : /// comparison operator
73 : bool operator==(const MultiIndex& o) const
74 : {
75 : for(size_t i=0; i < N; ++i)
76 : if(m_indices[i] != o[i]) return false;
77 : return true;
78 : }
79 :
80 : bool operator!=(const MultiIndex& o) const
81 : {
82 : return !(*this==o);
83 : }
84 :
85 : private:
86 : single_index_type m_indices[N];
87 : };
88 :
89 : // specialization of 1
90 : template <>
91 : class MultiIndex<1, size_t>
92 : {
93 : public:
94 : typedef size_t single_index_type;
95 :
96 : public:
97 : /// Default constructor
98 : MultiIndex(){};
99 :
100 : /// Constructor with values
101 : MultiIndex(single_index_type a)
102 : : m_indices(a)
103 : {};
104 :
105 : /// number of indices in multi index
106 : inline size_t size() const {return 1;}
107 :
108 : /// access to index component
109 : inline single_index_type& operator[] (size_t i)
110 : {
111 : UG_ASSERT(i == 0, "Index invalid");
112 : return m_indices;
113 : }
114 :
115 : /// const access to index component
116 : inline const single_index_type& operator[] (size_t i) const
117 : {
118 : UG_ASSERT(i == 0, "Index invalid");
119 : return m_indices;
120 : }
121 :
122 : /// comparison operator
123 : bool operator==(const MultiIndex& o) const
124 : {
125 : return m_indices == o[0];
126 : }
127 :
128 : bool operator!=(const MultiIndex& o) const
129 : {
130 : return !(*this==o);
131 : }
132 :
133 : private:
134 : single_index_type m_indices;
135 : };
136 :
137 : // specialization of 2
138 : template <>
139 : class MultiIndex<2, size_t>
140 : {
141 : public:
142 : typedef size_t single_index_type;
143 :
144 : public:
145 : /// Default constructor
146 0 : MultiIndex(){};
147 :
148 : /// Constructor with values
149 0 : MultiIndex(single_index_type a, single_index_type b){
150 0 : m_indices[0] = a;
151 0 : m_indices[1] = b;
152 : }
153 :
154 : /// number of indices in multi index
155 : inline size_t size() const {return 2;}
156 :
157 : /// access to index component
158 : inline single_index_type& operator[] (size_t i)
159 : {
160 : UG_ASSERT(i < 2, "Index invalid");
161 0 : return m_indices[i];
162 : }
163 :
164 : /// const access to index component
165 : inline const single_index_type& operator[] (size_t i) const
166 : {
167 : UG_ASSERT(i < 2, "Index invalid");
168 : return m_indices[i];
169 : }
170 :
171 : /// comparison operator
172 : bool operator==(const MultiIndex& o) const
173 : {
174 0 : return (m_indices[0] == o[0]) && (m_indices[1] == o[1]);
175 : }
176 :
177 : bool operator!=(const MultiIndex& o) const
178 : {
179 : return (m_indices[0] != o[0]) || (m_indices[1] != o[1]);
180 : }
181 :
182 : bool operator<(const MultiIndex& o) const
183 : {
184 0 : if(m_indices[0] < o[0]) return true;
185 0 : if(m_indices[0] == o[0])
186 0 : if(m_indices[1] < o[1]) return true;
187 : return false;
188 : }
189 :
190 : bool operator>(const MultiIndex& o) const
191 : {
192 : if(m_indices[0] > o[0]) return true;
193 : if(m_indices[0] == o[0])
194 : if(m_indices[1] > o[1]) return true;
195 : return false;
196 : }
197 :
198 : private:
199 : single_index_type m_indices[2];
200 : };
201 :
202 : // specialization of 3
203 : template <>
204 : class MultiIndex<3, size_t>
205 : {
206 : public:
207 : typedef size_t single_index_type;
208 :
209 : public:
210 : /// Default constructor
211 : MultiIndex(){};
212 :
213 : /// Constructor with values
214 : MultiIndex(single_index_type a, single_index_type b, single_index_type c){
215 : m_indices[0] = a;
216 : m_indices[1] = b;
217 : m_indices[2] = c;
218 : }
219 :
220 : /// number of indices in multi index
221 : inline size_t size() const {return 3;}
222 :
223 : /// access to index component
224 : inline single_index_type& operator[] (size_t i)
225 : {
226 : UG_ASSERT(i < 3, "Index invalid");
227 : return m_indices[i];
228 : }
229 :
230 : /// const access to index component
231 : inline const single_index_type& operator[] (size_t i) const
232 : {
233 : UG_ASSERT(i < 3, "Index invalid");
234 : return m_indices[i];
235 : }
236 :
237 : /// comparison operator
238 : bool operator==(const MultiIndex& o) const
239 : {
240 : return (m_indices[0] == o[0]) &&
241 : (m_indices[1] == o[1]) &&
242 : (m_indices[2] == o[2]);
243 : }
244 :
245 : bool operator!=(const MultiIndex& o) const
246 : {
247 : return !(*this==o);
248 : }
249 :
250 : private:
251 : single_index_type m_indices[3];
252 : };
253 :
254 : template <int N>
255 0 : std::ostream& operator<< (std::ostream& outStream, const ug::MultiIndex<N>& v)
256 : {
257 0 : outStream << "[" ;
258 0 : for(size_t i = 0; i < N; ++i)
259 : {
260 0 : outStream << v[i];
261 0 : if(i != N-1) outStream << ",";
262 : }
263 0 : outStream << "]";
264 0 : return outStream;
265 : }
266 :
267 : ////////////////////////////////////////////////////////////////////////////////
268 : // degree of freedom access using multi indices
269 : ////////////////////////////////////////////////////////////////////////////////
270 :
271 : /// type of DoF-Index used to identify an DoF in the Algebra
272 : typedef MultiIndex<2> DoFIndex;
273 :
274 : template <typename TMatrix>
275 : inline number&
276 : DoFRef(TMatrix& mat, const DoFIndex& iInd, const DoFIndex& jInd)
277 : {
278 0 : return BlockRef(mat(iInd[0], jInd[0]), iInd[1], jInd[1]);
279 : }
280 :
281 : template <typename TMatrix>
282 : inline const number&
283 : DoFRef(const TMatrix& mat, const DoFIndex& iInd, const DoFIndex& jInd)
284 : {
285 0 : return BlockRef(mat(iInd[0], jInd[0]), iInd[1], jInd[1]);
286 : }
287 :
288 : template <typename TVector>
289 : inline number&
290 : DoFRef(TVector& vec, const DoFIndex& ind)
291 : {
292 0 : return BlockRef(vec[ind[0]], ind[1]);
293 : }
294 :
295 : template <typename TVector>
296 : inline const number&
297 : DoFRef(const TVector& vec, const DoFIndex& ind)
298 : {
299 0 : return BlockRef(vec[ind[0]], ind[1]);
300 : }
301 :
302 : template <typename TMatrix>
303 : void SetDirichletRow(TMatrix& mat, const DoFIndex& ind)
304 : {
305 0 : SetDirichletRow(mat, ind[0], ind[1]);
306 0 : }
307 :
308 : template <typename TMatrix>
309 : void SetRow(TMatrix& mat, const DoFIndex& ind, number val = 0.0)
310 : {
311 0 : SetRow(mat, ind[0], ind[1], val);
312 0 : }
313 :
314 : }
315 :
316 :
317 : #endif /* __H__UG__LIB_DISC__COMMON__MULTI_INDEX__ */
|